223 lines
5.7 KiB
TypeScript
223 lines
5.7 KiB
TypeScript
import { ReactNode, useMemo, useState } from "react";
|
||
import { Button, Dropdown, Space } from "antd";
|
||
import { useNavigate } from "react-router-dom";
|
||
import type { ColumnsType } from "antd/es/table";
|
||
import {
|
||
DataTable,
|
||
ColumnSettings,
|
||
useVisibleColumns,
|
||
useFilteredRows,
|
||
} from "../../components/GenericTable";
|
||
import { EllipsisOutlined } from "@ant-design/icons";
|
||
import { useTableFilters } from "../../components/GenericTable/useTableFilters";
|
||
import { RelatedGroupOut } from "../../types/api";
|
||
import { relateGroupConfig } from "./config";
|
||
import { RelatedGroupForm } from "../RelatedGroupForm/RelatedGroupForm";
|
||
import { RelatedGroupFormType } from "../../types/relatedGroup/relatedGroup";
|
||
import {
|
||
deleteRelatedGroup,
|
||
editRelatedGroup,
|
||
} from "../../services/api/directories/related-groups";
|
||
import { DeleteRelatedGroupModal } from "../DeleteRelatedGroupModal/DeleteRelatedGroupModal";
|
||
import { useNotificationApi } from "../../utils/useNotification";
|
||
import { ApiError } from "../../api/client";
|
||
|
||
interface RelatedGroupTableI {
|
||
tabsComponent?: ReactNode;
|
||
data: RelatedGroupOut[];
|
||
loading: boolean;
|
||
getData: () => void;
|
||
activeTab: "gsk" | "gsz";
|
||
}
|
||
|
||
export function RelatedGroupTable({
|
||
tabsComponent,
|
||
data,
|
||
loading,
|
||
getData,
|
||
activeTab,
|
||
}: RelatedGroupTableI) {
|
||
const navigate = useNavigate();
|
||
const notification = useNotificationApi();
|
||
|
||
const [editFormOpen, setEditFormOpen] = useState(false);
|
||
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
|
||
const [deletingLoading, setDeletingLoading] = useState(false);
|
||
const [groupId, setGroupId] = useState("");
|
||
|
||
const { visibleKeys, setVisibleKeys } = useVisibleColumns(relateGroupConfig);
|
||
const {
|
||
rawQuery,
|
||
columnFilters,
|
||
setColumnFilters,
|
||
sort,
|
||
setSort,
|
||
resetAll,
|
||
hasActiveFilters,
|
||
} = useTableFilters<RelatedGroupOut>();
|
||
// single filtered array — title count and table share it
|
||
const { rows } = useFilteredRows(
|
||
data,
|
||
relateGroupConfig,
|
||
rawQuery,
|
||
columnFilters,
|
||
sort,
|
||
);
|
||
|
||
function closeEditRelatedGroupHandler() {
|
||
setGroupId("");
|
||
setEditFormOpen(false);
|
||
}
|
||
function closeDeleteRelatedGroupHandler() {
|
||
setGroupId("");
|
||
setDeleteModalOpen(false);
|
||
}
|
||
|
||
async function deleteRelatedGroupHandler() {
|
||
try {
|
||
setDeletingLoading(true);
|
||
await deleteRelatedGroup(groupId);
|
||
getData();
|
||
setDeleteModalOpen(false);
|
||
setGroupId("");
|
||
} catch (e) {
|
||
if (e instanceof ApiError) {
|
||
notification.error({
|
||
description: e.message,
|
||
});
|
||
}
|
||
} finally {
|
||
setDeletingLoading(false);
|
||
}
|
||
}
|
||
|
||
async function editRelatedGroupHandler(values: RelatedGroupFormType) {
|
||
try {
|
||
await editRelatedGroup(groupId, values);
|
||
getData();
|
||
closeEditRelatedGroupHandler();
|
||
} catch (e) {
|
||
if (e instanceof ApiError) {
|
||
notification.error({
|
||
description: e.message,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
const extraColumns: ColumnsType<RelatedGroupOut> = useMemo(
|
||
() => [
|
||
{
|
||
key: "actions",
|
||
title: "",
|
||
width: 30,
|
||
render: (_: unknown, row: RelatedGroupOut) => {
|
||
const items = [
|
||
{
|
||
key: "edit",
|
||
label: "Изменить",
|
||
onClick: () => {
|
||
setGroupId(row.id);
|
||
setEditFormOpen(true);
|
||
},
|
||
},
|
||
{
|
||
key: "delete",
|
||
label: "Удалить",
|
||
danger: true,
|
||
onClick: () => {
|
||
setGroupId(row.id);
|
||
setDeleteModalOpen(true);
|
||
},
|
||
},
|
||
];
|
||
return (
|
||
<Dropdown menu={{ items }} trigger={["click"]}>
|
||
<Button type="default" style={{ width: "32px" }}>
|
||
<EllipsisOutlined />
|
||
</Button>
|
||
</Dropdown>
|
||
);
|
||
},
|
||
},
|
||
],
|
||
[navigate],
|
||
);
|
||
|
||
return (
|
||
<div
|
||
style={{
|
||
width: "100%",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
height: "100%",
|
||
background: "white",
|
||
borderRadius: 12,
|
||
}}
|
||
>
|
||
<Space
|
||
style={{
|
||
padding: "0 12px",
|
||
width: "100%",
|
||
justifyContent: "space-between",
|
||
borderBottom: "1px",
|
||
}}
|
||
>
|
||
{tabsComponent}
|
||
|
||
<Space>
|
||
{hasActiveFilters && (
|
||
<Button
|
||
type="default"
|
||
onClick={() => {
|
||
resetAll();
|
||
}}
|
||
>
|
||
Сбросить фильтры
|
||
</Button>
|
||
)}
|
||
<ColumnSettings
|
||
defs={relateGroupConfig.columns}
|
||
visibleKeys={visibleKeys}
|
||
onChange={setVisibleKeys}
|
||
/>
|
||
</Space>
|
||
</Space>
|
||
<DataTable
|
||
sortState={sort}
|
||
onSortChange={setSort}
|
||
config={relateGroupConfig}
|
||
loading={loading}
|
||
rows={rows}
|
||
allRows={data}
|
||
visibleKeys={visibleKeys}
|
||
globalQuery={rawQuery}
|
||
columnFilters={columnFilters}
|
||
onColumnFiltersChange={setColumnFilters}
|
||
extraColumns={extraColumns}
|
||
/>
|
||
{editFormOpen && (
|
||
<RelatedGroupForm
|
||
kind={activeTab}
|
||
relatedGroupId={groupId}
|
||
open={editFormOpen}
|
||
onCancel={() => {
|
||
closeEditRelatedGroupHandler();
|
||
}}
|
||
onOk={async (values) => {
|
||
await editRelatedGroupHandler(values);
|
||
}}
|
||
/>
|
||
)}
|
||
{deleteModalOpen && (
|
||
<DeleteRelatedGroupModal
|
||
open={deleteModalOpen}
|
||
loading={deletingLoading}
|
||
onCancel={() => closeDeleteRelatedGroupHandler()}
|
||
onOk={deleteRelatedGroupHandler}
|
||
/>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|