e.stopPropagation()}
+ >
+ {sort && (
+ <>
+
+ Сортировка
+
+
{
+ const v = e.target.value;
+ setDraftSort(v === NO_SORT ? null : (v as "asc" | "desc"));
+ }}
+ style={{ display: "flex", flexDirection: "column", gap: 4 }}
+ >
+
+ Нет
+
+
+ По возрастанию
+
+
+ По убыванию
+
+
+ {(search || multiselect) &&
}
+ >
+ )}
+
+ {search && (
+
}
+ value={query}
+ onChange={(e) => setQuery(e.target.value)}
+ style={{ marginBottom: 8 }}
+ />
+ )}
+
+ {multiselect && filteredOptions.length > 0 && (
+ <>
+
+
+
+
+
+
+
+ setDraftKeys(vals as React.Key[])}
+ style={{ display: "flex", flexDirection: "column", gap: 4 }}
+ >
+ {filteredOptions.map((o) => (
+
+ {o.label}
+
+ ))}
+
+
+ >
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/GenericTable/DataTable.tsx b/src/components/GenericTable/DataTable.tsx
new file mode 100644
index 0000000..90b05a0
--- /dev/null
+++ b/src/components/GenericTable/DataTable.tsx
@@ -0,0 +1,223 @@
+import { useLayoutEffect, useMemo, useRef, useState } from "react";
+import { Table } from "antd";
+import Icon, { FilterFilled, FilterOutlined } from "@ant-design/icons";
+import type { ColumnGroupType, ColumnsType, ColumnType } from "antd/es/table";
+import type { TableProps } from "antd";
+import { CustomFilterDropdown } from "./CustomFilterDropdown";
+import { Highlight } from "./Highlight";
+import {
+ isGroup,
+ LeafColumnDef,
+ type ColumnFilters,
+ type FilterOption,
+ type SortState,
+ type TableConfig,
+} from "./tableTypes";
+type ExtraColumn