File "ProjectPage.tsx"

Full Path: /var/www/html/gitep_front/src/pages/ProjectPage/ProjectPage.tsx
File size: 33.2 KB
MIME-type: text/x-java
Charset: utf-8

import TableComponent from "@/shared/ui/TableComponent/TableComponent";
import {Button, Checkbox, Flex, notification, Tag, Typography, Modal, Tooltip} from "antd";
import { TableRowSelection } from "antd/es/table/interface";
import React, { useEffect, useMemo, useState, useRef } from "react";
import { useMediaQuery } from "react-responsive";
import styles from './project.module.scss';
import { HeaderProject } from "./header/Header";
import { SortableBlock } from "./SortableBlock/SortableBlock";
import { useUnit } from "effector-react";

import ArrowShow from "@shared/assets/images/icons/arrow-show.svg?react";
import ArrowShowRight from "@shared/assets/images/icons/arrow-show-right.svg?react";
import { TotalBlock } from "./TotalBlock/TotalBlock";
import { DrawerComponent } from "@/shared/ui/DrawerComponent/DrawerComponent";
import { AddGroupContent } from "./addGroup/AddGroupContent";
import { AddProjectContent } from "./addProject/AddProjectContent";
import { GroupReadDrawer } from "./groupReadDrawer/groupReadDrawer";
import { createGroup } from "@/entities/payment-card/api/createGroup";
import { getGroupList } from "@/entities/payment-card/api/getGroupList";
import { createProject } from "@/entities/payment-card/api/createProject";
import { ProjectReadDrawer } from "./projectReadDrawer/ProjectReadDrawer";
import { getProjectItem } from "@/entities/project/api/getProjectItem";
import { getGroupProject } from "@/entities/project/api/getGroupProject";
import { updateProject } from "@/entities/payment-card/api/updateProject";
import { updateGroup } from "@/entities/payment-card/api/updateGroup";
import { postExcelFile } from "@/entities/project/api/postExcelFile";
import { $projectItemStore } from "@/entities/project/model";
import { useStore } from "effector-react";
import { $roleStore, $permissionStore } from "@features/roles/store/stores"
import isEqual from 'lodash.isequal';
import { Helmet } from "react-helmet";
import { formatWholeSum } from '@/shared/lib';

const getAllChildKeys = (data: any[], key: string): React.Key[] => {
  const group = data.find(item => item.key === key);
  return group?.children?.map((child: any) => child.key) || [];
};

const defaultProjectData = {
  offer_number: '',
  object_address: '',
  short_description: '',
  description: '',
  project_group_id: '',
  project_limits: 1222,
  status: 'active'
}

const defaultGroupData = {
  name: '',
  description: '',
  projects: []
}

interface IStats {
  in_work: number
  income: number
  outcome: number
}

export const ProjectPage = () => {
    const tableToBig = useMediaQuery({ query: '(min-width: 769px)' })
    const projectDataItem = useUnit($projectItemStore);

    const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
    const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>([]);

    const [sortField, setSortField] = useState<string>('name');
    const [sortDirection, setSortDirection] = useState<'ASC' | 'DESC'>('ASC');
    const [currentTab, setCurrentTab] = useState('current')

    const [isRowDrawerOpen, setIsRowDrawerOpen] = useState(false);
    const [openChildRow, setOpenChildRow] = useState(false);

    const [isAddProject, setIsAddProject] = useState(false)
    const [isAddGroup, setIsAddGroup] = useState(false)

    const [recordData, setRecordData]: any = useState(null)
    const [projectItemData, setProjectItemData]: any = useState(null)
    const [groupItemData, setGroupItemData]: any = useState(null)

    const [projects, setProjects] = useState([])
    const [stats, setStats] = useState<IStats>({in_work: 0, income: 0, outcome: 0})
    const [search, setSearch] = useState('')

    const [isEditDrawer, setIsEditDrawer] = useState(false)
    const[IsEditablebyRole, setIsEditableByRole] = useState(true);

    const [isModalOpen, setIsModalOpen] = useState(false);
    const [isModalProjectOpen, setIsModalProjectOpen] = useState(false);
    const [initialGroupData, setInitialGroupData] = useState(defaultGroupData);
    const [initialProjectData, setInitialProjectData] = useState(defaultProjectData);

    const roleStore = useUnit($roleStore).role;
    
    const transformedData = useMemo(() => {
      return projects?.map((group: any, groupIndex) => ({
        key: group.id ? `group_${group.id}` : `ungrouped_${groupIndex}`,
        id: group.id ? group.id : '', 
        supplier: group.name,
        totalAmountPayments: group.total_payments?.total_amount_payment,
        inProcess: group.total_payments?.in_process,
        isGroup: true,
        total_amounts: {
          total_credit: group.total_amounts.total_credit,
          total_debit: group.total_amounts.total_debit,
        },
        total_limits: {
          credit: group.total_limits.credit,
          debit: group.total_limits.debit,
        },
        subtitle: group.description || '',
        children: group.projects.map((project: any, projectIndex: number) => ({
          key: project.id ? `${project.id}` : '',
          supplier: project.offer_number,
          totalAmountPayments: project?.project_payments?.total_amount_payment,
          inProcess: project?.project_payments?.in_process,
          isGroup: false,
          total_amounts: {
            total_credit: project.project_amounts.credit,
            total_debit: project.project_amounts.debit,
          },
          total_limits: {
            credit: project.project_limits.credit,
            debit: project.project_limits.debit,
          },
          payments: 0,
          ...project,
        })),
      }));
    }, [projects]);

    const prevTransformedRef = React.useRef<any[]>([]);

    useEffect(() => {
      if (!search) {
        prevTransformedRef.current = transformedData;
        return;
      }
      if (expandedRowKeys.length > 0) return;
      if (isEqual(prevTransformedRef.current, transformedData)) {
        prevTransformedRef.current = transformedData;
        return;
      }
      const defaultGroupKeys = transformedData
        .filter((g: any) => g.isGroup)
        .map((g: any) => g.key);

      if (defaultGroupKeys.length > 0) {
        setExpandedRowKeys(defaultGroupKeys as React.Key[]);
      }
      prevTransformedRef.current = transformedData;
    }, [search, transformedData, expandedRowKeys]);

    const [groupData, setGroupData]: any = useState({
      name: '',
      description: '',
      projects: [],
    })
    const [projectData, setProjectData] = useState({
      offer_number: '',
      object_address: '',
      short_description: '',
      description: '',
      project_group_id: '',
      project_limits: 1222,
      status: 'active'
    })

    const [projectId, setProjectId] = useState(null)
    const [groupId, setGroupId] = useState(null)
    const getProject = async() => {
      const { data }: any = await getGroupList({
        search: search,
        sort: sortField,
        sort_direction: sortDirection,
        type: currentTab
      })

      const ungroupedProjects = data.data.projects_without_groups || [];
  
      const ungroupedTotals = ungroupedProjects.reduce(
        (acc: any, project: any) => {
          acc.credit += parseFloat(project.project_limits.credit) || 0;
          acc.debit += parseFloat(project.project_limits.debit) || 0;
          acc.total_credit += project.project_amounts.credit || 0;
          acc.total_debit += project.project_amounts.debit || 0;
          return acc;
        },
        { credit: 0, debit: 0, total_credit: 0, total_debit: 0 }
      );

      const totalPayments = ungroupedProjects.reduce(
          (acc: any, project: any) => {
              return {
                  in_process: acc.in_process + (project.total_payments?.in_process || 0),
                  total_amount_payment:
                      acc.total_amount_payment + (project.total_payments?.total_amount_payment || 0),
              };},
          { in_process: 0, total_amount_payment: 0 }
      );

        const ungroupedGroup = {
        id: null,
        name: "Не в группе",
        description: null,
        total_limits: {
          credit: ungroupedTotals.credit,
          debit: ungroupedTotals.debit,
        },
        total_amounts: {
          total_credit: ungroupedTotals.total_credit,
          total_debit: ungroupedTotals.total_debit,
        },
        total_payments: totalPayments,
        projects: ungroupedProjects,
      };

      const allGroups: any = [ungroupedGroup, ...(data.data.projects_groups || [])];
      setProjects(allGroups);
      setStats(data.data.header)
    }

    useEffect(() => {
    }, [projectDataItem])

    
    useEffect(() => {
      getProject()
    }, [search, sortField, sortDirection, currentTab])

    const isFirstRenderGroup = useRef(true);

    useEffect(() => {
      if (isFirstRenderGroup.current && isAddGroup) {
        setInitialGroupData({ ...groupData });
        isFirstRenderGroup.current = false;
      }
    }, [isAddGroup]);

    const isFirstRender = useRef(true);

    useEffect(() => {
      // if (isFirstRender.current && isAddProject) {
        setInitialProjectData({...projectData});
        isFirstRender.current = false;
      // }
    }, [isAddProject]);

    const formatterNumberPayments = (value: number): string => {
        const absValue = Math.abs(value);
        const lastTwo = absValue % 100;
        const lastOne = absValue % 10;

        if (lastTwo >= 11 && lastTwo <= 14) {
            return `${value} платежей`;
        }

        if (lastOne === 1) {
            return `${value} платеж`;
        }

        if (lastOne >= 2 && lastOne <= 4) {
            return `${value} платежа`;
        }

        return `${value} платежей`;
    };


    const columns = [
      {
        title: <Flex style={{marginLeft: '30px'}}>Название</Flex>,
        dataIndex: 'supplier',
        key: 'article',
        render: (value:any, record: any) => {
            const fullText = `${value} ${record.object_address ? `| ${record.object_address}` : ''} ${record.short_description ? `| ${record.short_description}` : ''}`;

            return (
                <Tooltip placement="bottomRight" color="#344054" title={fullText}>
                     <span className={styles.projectName} style={{marginLeft: '30px'}}>
                        {!record.children ? fullText : value}
                    </span>
                </Tooltip>
            )
        }
      },
        {
            title: <Flex justify="end">Доходы, ₽</Flex>,
            width: 140,
            key: 'total_amounts',
            dataIndex: 'total_amounts',
            render: (value: number, record: any) => <Flex style={{flexDirection: 'column', lineHeight: '1.3', marginLeft: 'auto'}} align="end"><span style={{color: '#52C41A'}}>{formatWholeSum(record.total_amounts.total_credit)}</span> <span style={{color: '#98A2B3', fontSize: '12px', fontWeight: 400}}>{`[${formatWholeSum(record.total_limits.credit)}]`}</span></Flex>
      },
      {
        title: <Flex justify="end">Расходы, ₽</Flex>,
        dataIndex: 'expense',
        key: 'expense',
        width: 140,
        render: (value: number, record: any) =>  record.children ? (
          <Flex style={{flexDirection: 'column', lineHeight: '1.3', marginLeft: 'auto'}} align="end"><span style={{color: '#101828'}}>{formatWholeSum(+record.total_amounts.total_debit)}</span> <span style={{color: '#FF4d4F', fontSize: '12px', fontWeight: 400}}>[{formatWholeSum(+record.total_limits.debit)}]</span></Flex>
       ) : <Flex style={{flexDirection: 'column', lineHeight: '1.3', marginLeft: 'auto'}} align="end"><span style={{color: '#101828'}}>{formatWholeSum(record.total_amounts.total_debit)}</span> <span style={{color: '#FF4d4F', fontSize: '12px', fontWeight: 400}}>{`[${formatWholeSum(+record.total_limits.debit)}]`}</span></Flex>,
     },
      {
        title: 'Платежи в процессе',
        dataIndex: 'payments',
        width: 200,
        render: (value: number, record: any) => (
            <Flex gap={8}>
                <Tag color="#EAECF0" style={{ color: '#101828' }}>
                    {formatterNumberPayments(record?.inProcess || record?.total_payments?.in_process || 0)} ┆ {formatWholeSum(record.totalAmountPayments || record?.total_payments?.total_amount_payment || 0)} ₽
                </Tag>
            </Flex>
        ),
      },
    ];

    const { totalIncome, totalExpense, selectedCount } = useMemo(() => {
      const selectedKeysSet = new Set(selectedKeys);
      let totalIncome = 0;
      let totalExpense = 0;
      let count = 0;
    
      transformedData.forEach(group => {
        if (selectedKeysSet.has(group.key)) {
          totalIncome += group.total_amounts.total_credit || 0;
          totalExpense += group.total_amounts.total_debit || 0;
          count++;
          return;
        }
    
        group.children?.forEach((project: any) => {
          if (selectedKeysSet.has(project.key)) {
            totalIncome += project.total_amounts.total_credit || 0;
            totalExpense += project.total_amounts.total_debit || 0;
            count++;
          }
        });
      });
      return { totalIncome, totalExpense, selectedCount: count };
    }, [selectedKeys, transformedData]);


        const permissionsRaw = useUnit($permissionStore).permissions as any;
        const permissionsStore = Array.isArray(permissionsRaw)
          ? permissionsRaw
          : typeof permissionsRaw === 'string'
            ? permissionsRaw.split(',').filter(Boolean)
            : [];      
        const allowedRoles: any = ['accountant', 'superAdmin'];
        const allowedCollaboratorProject: any = ['collaborator'];

        const isAllowedProjectEdit = () => {
            const isRoleAllowed = allowedRoles.includes(roleStore);
        
            return (
                (isRoleAllowed) ||
                (allowedCollaboratorProject && permissionsStore.includes("project_management"))
            );
        };

    const handleRowClick = (record: any) => {
      return {
        onClick: async (event: React.MouseEvent) => {
          if (record.isGroup) {
            event.stopPropagation();
            const { data }: any = await getGroupProject(record.id)
            setGroupItemData(data.data)
            setIsRowDrawerOpen(true);
            setRecordData(record)
            setIsEditableByRole(isAllowedProjectEdit())
          }
          if (!record.isGroup) {
            event.stopPropagation();
            const { data }: any = await getProjectItem(record.id)
            setProjectItemData(data.data)
            setOpenChildRow(true)
            setRecordData(record)
            setIsEditableByRole(isAllowedProjectEdit())

          }
        },
      };
    };

    const handleGroupSelect = (groupKey: string, checked: boolean) => {
      const childKeys = getAllChildKeys(transformedData, groupKey);
      setSelectedKeys(prev => 
        checked 
          ? [...prev, ...childKeys] 
          : prev.filter(k => !childKeys.includes(k))
      );
    };
  
    const handleSingleSelect = (key: React.Key, checked: boolean) => {
      setSelectedKeys(prev => 
        checked 
          ? [...prev, key] 
          : prev.filter(k => k !== key)
      );
    };
  
    const rowSelection: TableRowSelection<any> = useMemo(() => ({
      selectedRowKeys: selectedKeys,
      onChange: (keys) => setSelectedKeys(keys || []),
      columnWidth: 45,
      renderCell: (checked, record) => {
        const stop = (e: React.MouseEvent) => {
            e.stopPropagation();
        };

        if (record.isGroup) {
          const childrenKeys = getAllChildKeys(transformedData, record.key);

          const allSelected = childrenKeys.every(k => selectedKeys.includes(k));
          const indeterminate = !allSelected && childrenKeys.some(k => selectedKeys.includes(k));

          if (childrenKeys.length === 0 && !record.project_group_id) {
            return (
            <div onClick={stop}>
              <Checkbox
                checked={checked}
                onClick={(e) => {
                   e.stopPropagation();
                   handleSingleSelect(record.key, !checked);
                }}
              />
            </div>
          )}
                    
  
          return (
            <div onClick={stop}>
              <Checkbox
                 checked={allSelected}
                 indeterminate={indeterminate}
                 onClick={(e) => {
                    e.stopPropagation();
                    handleGroupSelect(record.key, !allSelected);
                 }}
              />
            </div>
          );
        }
        return (
          <div onClick={stop}>
            <Checkbox
              checked={checked}
              onClick={(e) => {
                e.stopPropagation();
                handleSingleSelect(record.key, !checked);
              }}
            />
          </div>
        );
      }
    }), [selectedKeys, transformedData]);


    const createGroupHandler = async() => {
      try {
        await createGroup(groupData);
        notification.success({
          message: 'Успех',
          description: 'Группа успешно создана',
        });
        getProject()
        setIsAddGroup(false);
        setGroupData(defaultGroupData)
        await getProject();
      } catch (err) {
        notification.error({
          message: 'Ошибка',
          description: 'Не удалось создать группу',
        });
      }
    }

    const createProjectHandler = async() => {
      
      try{
        await createProject(projectData)
        notification.success({
          message: 'Успех',
          description: 'Проект успешно создан',
        });
        getProject()
        setIsAddProject(false);
        setProjectData(defaultProjectData)
      }catch(err) {
        notification.error({
          message: 'Ошибка',
          description: 'Не удалось создать проект',
        });
      }
    }

    const updateProjectHandler = async() => {
      if(!projectId) {
        return
      }
      try{
        await updateProject(projectData, projectId)

      setRecordData({
        description: projectData.description,
        supplier: projectData.offer_number,
        object_address: projectData.object_address,
        short_description: projectData.short_description,
        id: projectData.project_group_id,
      });
        notification.success({
          message: 'Успех',
          description: 'Проект успешно отредактирован',
        });
        getProject()
        setIsAddProject(false);
        // setOpenChildRow(false)
        setIsEditDrawer(false);
        setProjectData(defaultProjectData);
        setInitialProjectData({...projectData});
      }catch(err) {
        notification.error({
          message: 'Ошибка',
          description: 'Не удалось отредактировать проект',
        });
      }
    }


    const updateGroupHandler = async() => {
      if(!groupId) {
        return
      }
      try{
        const payload = {
          ...groupData,
          projects: groupData.projects.join(',')
        };

      await updateGroup(payload, groupId)
      setRecordData({
        supplier: groupData.name,
      });
        notification.success({
          message: 'Успех',
          description: 'Группа успешно отредактирована',
        });
        getProject()
        setIsAddGroup(false);
        // setIsRowDrawerOpen(false)
        setGroupData(defaultGroupData)
      }catch(err) {
        notification.error({
          message: 'Ошибка',
          description: 'Не удалось отредактировать группу',
        });
      }
    }

    const excelUpload = async () => {
      try {
        const filteredArrayOfSelectedKeys = selectedKeys.filter((item:any) => !isNaN(item));

        const { data }: any = await postExcelFile({ids: filteredArrayOfSelectedKeys});
        const originalUrl = data.data.url;
        // const modifiedUrl = originalUrl
        //   .replace('gitep.dev-top-it.ru', 'gitep.dev-top-it.ru:8080');

        const relativePath = originalUrl.split('://')[1]?.split('/').slice(1).join('/');
        const modifiedUrl = originalUrl
          ? new URL(`/${relativePath}`, import.meta.env.VITE_BASE_URL).href
          : undefined;
            
            if (modifiedUrl) {
              const encodedUrl = encodeURI(modifiedUrl);
              window.open(encodedUrl, '_blank');
            }
            
          } catch (error) {
            console.error('Ошибка загрузки файла:', error);
          }
    };

    const handleSortChange = (field: string, direction: 'ASC' | 'DESC') => {
      setSortField(field);
      setSortDirection(direction);
    };
  
    const handleSegmentChange = (value: string) => {
      if(value === 'current') {
          setCurrentTab('current')
      } else {
          setCurrentTab('archive')
      }
    };

    const closeWithoutSave = () => {
      setIsModalOpen(false);
      setIsModalProjectOpen(false);
      setGroupData(defaultGroupData);
      setProjectData(defaultProjectData);
    };

  const tableRef = useRef<HTMLDivElement>(null);
  const [tableHeight, setTableHeight] = useState(600);

  useEffect(() => {
    const calculateHeight = () => {
      if (tableRef.current) {
        const viewportHeight = window.innerHeight;
        const tableTop = 130;
        const paddingBottom = 100;
        const height = viewportHeight - tableTop - paddingBottom;
        setTableHeight(Math.max(height, 300));
      }
    };

    calculateHeight();
    window.addEventListener('resize', calculateHeight);
    return () => window.removeEventListener('resize', calculateHeight);
  }, []);

  return (
    <div className={styles.wrapper}>
          <Helmet>
            <title>Проекты | Платежи</title>
          </Helmet>
          {tableToBig && <HeaderProject transformedData={transformedData} workLength={stats.in_work} income={stats.income} outcome={stats.outcome} /> }
          <SortableBlock
            sortField={sortField}
            sortDirection={sortDirection}
            onSortChange={handleSortChange}
            currentTab={currentTab}
            handleSegmentChange={handleSegmentChange}
            onSearch={(value) => setSearch(value)}
            setAddGroup={() => setIsAddGroup(true)}
            setAddProject={() => setIsAddProject(true)}
            roleStore={roleStore}
          />

            <Flex vertical style={{ height: 'calc(100vh - 172px)' }}>
              <TableComponent
                tableRef={tableRef}
                columns={columns}
                dataSource={transformedData}
                className={styles.wrapperTable}
                rowSelection={rowSelection}
                groupedView
                rowClassName={(record) => 
                  record.isGroupHeader ? 'group-row' : 'child-row'
                }
                expandable={{
                  expandedRowKeys,
                  onExpand: (expanded, record) => {
                    setExpandedRowKeys(prev => 
                      expanded 
                        ? [...prev, record.key] 
                        : prev.filter(key => key !== record.key))
                  },
                }}
                expandIcon={({ expanded, onExpand, record }) =>
                  record.children && record.children.length > 0 ? (
                    <span
                      onClick={(e) => {
                        e.stopPropagation()
                        onExpand(record, e)
                      }}
                      style={{ marginRight: 8, transition: "all 0.3s", position: 'absolute', left: '14px', top: '20px' }}
                    >
                      {expanded ? (
                        <ArrowShow width={16} height={16} />
                      ) : (
                        <ArrowShowRight width={16} height={16} />
                      )}
                    </span>
                  ) : null
                }
                onRow={handleRowClick}
                virtual
                scroll={{ x: 'auto', y: tableHeight }}
                components={{
                  body: {
                    cell: (props: any) => (
                      <td {...props} style={{ ...props.style, display: 'flex', alignItems: 'center'}} />
                    ),
                  },
                }}
              />
              {selectedKeys.length ? (
                <TotalBlock
                downloadExcelHadler={excelUpload}
                selectedCount={selectedCount}
                totalIncome={totalIncome}
                totalExpense={totalExpense}
              />
              ) : ''}
            </Flex>
          
          {/* {selectedKeys.length ? (
            <TotalBlock
            downloadExcelHadler={excelUpload}
            selectedCount={selectedCount}
            totalIncome={totalIncome}
            totalExpense={totalExpense}
          />
          ) : ''} */}

          <DrawerComponent
            open={isAddGroup}
            zIndexCustom={2000}
            IsEditablebyRole={IsEditablebyRole}
            handleClose={async () => {
              getProject()
              // setGroupData(defaultGroupData)
              setIsEditDrawer(false)
              const isDataChanged = 
                groupData.name !== initialGroupData.name ||
                groupData.description !== initialGroupData.description ||
                !isEqual(groupData.projects, initialGroupData.projects);

              if (isDataChanged) {
                setIsModalOpen(true);
              } else {
                setGroupData(defaultGroupData);
              }
              setIsAddGroup(false)
            }}
            id={projectItemData?.id}
            title={`${isEditDrawer ? (recordData?.supplier ? recordData?.supplier: 'Название группы') : 'Новая группа'}`}
            content={<AddGroupContent
              isAddGroup={isAddGroup}
              isOpen={isAddGroup}
              isEdit={isEditDrawer}
              recordData={recordData}
              groupData={groupData}
              setGroupData={(data: any) => setGroupData({ ...groupData, ...data })}/>}
            footer={
              <Flex gap={12} className={styles.footer}>
                <Button onClick={() => setIsAddGroup(false)} size="large">Отменить</Button>
                <Button
                onClick={isEditDrawer ? updateGroupHandler : createGroupHandler}
                disabled={!groupData?.name?.trim()}
                  size="large"
                >Готово</Button>
              </Flex>
            }
            />
          <DrawerComponent
            open={isAddProject}
            zIndexCustom={2000}
            IsEditablebyRole={IsEditablebyRole}
            handleClose={async() => {
              getProject()
              setIsAddProject(false)
              setIsEditDrawer(false)
                const isDataChanged = !isEqual(projectData, initialProjectData);
                if (isDataChanged) {
                  setIsModalProjectOpen(true);
                } else {
                  setProjectData(defaultProjectData);
                }
                setInitialProjectData(defaultProjectData);
            }}
            id={projectItemData?.id}
            title={isEditDrawer ? `${recordData.supplier} | ${recordData.object_address} | ${recordData.short_description}` 
            : 'Новый проект'}
            content={
              <AddProjectContent isOpen={isAddProject} isEditDrawer={isEditDrawer} projectData={projectData} setProjectData={(data: Partial<typeof projectData>) => 
                setProjectData(prev => ({...prev, ...data}))}
              />}
            footer={
              <Flex gap={12} className={styles.footer}>
                <Button onClick={() => setIsAddProject(false)} size="large">Отменить</Button>
                <Button onClick={isEditDrawer ? updateProjectHandler : createProjectHandler} size="large">Готово</Button>
              </Flex>
            }
          />
          
          <DrawerComponent
            open={isRowDrawerOpen}
            handleClose={async() => {
              getProject()
              setIsRowDrawerOpen(false)
            }}
            title={recordData ? recordData.supplier : ''}
            id={projectItemData?.id}
            zIndexCustom={100}
            idGroup={recordData?.id}
            updateTable={() => getProject()}
            subtitle={recordData ? recordData.subtitle : ''}
            isRead
            clickEditItem={() => {
              setIsEditDrawer(true)
              setGroupId(recordData.id)
              setGroupData({
                name: groupItemData.name,
                description: groupItemData.description,
                projects: recordData?.children?.map((it: any) => it.id),
              })
              setIsAddGroup(true)
            }}
            width={900}
            content={<GroupReadDrawer isRowDrawerOpen={isRowDrawerOpen} idGroup={recordData?.id} openChildRow={isRowDrawerOpen} IsEditablebyRole={IsEditablebyRole}/>}
            footer={<></>}
            IsEditablebyRole={IsEditablebyRole}
          />

          <DrawerComponent
            open={openChildRow}
            handleClose={async() => {
              getProject()
              setOpenChildRow(false)
            }}
            projectItemData={projectItemData}
            zIndexCustom={100}
            clickEditItem={() => {
              setIsEditDrawer(true)
              setProjectId(recordData.id)
              setProjectData({
                offer_number: projectItemData.offer_number,
                object_address: projectItemData.object_address,
                short_description: projectItemData.short_description,
                description: projectItemData.description,
                project_group_id: projectItemData?.project_group?.id || null,
                project_limits: projectItemData.project_limits,
                status: projectItemData.status
              })
              setIsAddProject(true)
            }}
            id={projectItemData?.id}
            title={recordData ? `${recordData.supplier} | ${recordData.object_address} | ${recordData.short_description}` : ''}
            subtitle={recordData ? recordData.description : ''}
            isProject
            updateTable={() => getProject()}
            isRead
            width={900}
            content={<ProjectReadDrawer projectData={projectItemData} openChildRow={openChildRow} IsEditablebyRole={IsEditablebyRole} />}
            footer={<></>}
            IsEditablebyRole={IsEditablebyRole}
          />
          <Modal
              title={<p className={styles["modal-save__title"]}>Выйти без сохранения?</p>}
              className={styles["modal-save"]}
              width={460}
              closable={false}
              open={isModalOpen}
              onOk={() => (isEditDrawer ? updateGroupHandler : createGroupHandler)()}
              onCancel={() => setIsAddGroup(true)}
              footer={(_, { }) => (
                <>
                  <Button
                    style={{ width: '100%' }}
                    className="primary-red-btn"
                    onClick={() => closeWithoutSave()}
                  >
                    Закрыть без сохранения
                  </Button>
                </>
              )}
            >
            <Flex vertical gap={32}>
              <p className={styles["modal-save__text"]}>Данные не были сохранены. Хотите сохранить их перед выходом?</p>
            <Flex vertical gap={8}>
              <Button type="primary" key="back" onClick={() => (setIsAddGroup(true), setIsModalOpen(false))}>
                Вернуться
              </Button>
              <Button onClick={() => {(isEditDrawer ? updateGroupHandler : createGroupHandler)()
                setIsModalOpen(false)
              }}>
                Сохранить и закрыть
              </Button>
            </Flex>
          </Flex>
        </Modal>
        <Modal
            title={<p className={styles["modal-save__title"]}>Выйти без сохранения?</p>}
            className={styles["modal-save"]}
            width={460}
            closable={false}
            open={isModalProjectOpen}
            // onOk={() => (isEditDrawer ? updateProjectHandler : createProjectHandler)()}
            onCancel={() => setIsAddProject(false)}
            footer={(_, { }) => (
              <>
                <Button
                  style={{ width: '100%' }}
                  className="primary-red-btn"
                  onClick={() => closeWithoutSave()}
                >
                  Закрыть без сохранения
                </Button>
              </>
            )}
          >
            <Flex vertical gap={32}>
              <p className={styles["modal-save__text"]}>Данные не были сохранены. Хотите сохранить их перед выходом?</p>
            <Flex vertical gap={8}>
              <Button type="primary" key="back" onClick={() => (setProjectData({ ...projectData }), setIsAddProject(true), setIsModalProjectOpen(false))}>
                Вернуться
              </Button>
              <Button onClick={() => {(isEditDrawer ? updateProjectHandler : createProjectHandler)()
                  setIsModalProjectOpen(false)
              }}>
                Сохранить и закрыть
              </Button>
            </Flex>
          </Flex>
        </Modal>
    </div>
  );
};