|
|
|
@ -1,4 +1,4 @@
|
|
|
|
import React, { useCallback, useRef, useState } from "react";
|
|
|
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
|
|
import { Collapse, Empty, Table as AntdTable } from "antd";
|
|
|
|
import { Collapse, Empty, Table as AntdTable } from "antd";
|
|
|
|
import "./Table.css";
|
|
|
|
import "./Table.css";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
@ -7,7 +7,8 @@ import parse from "wellknown";
|
|
|
|
import { useMap } from "react-map-gl";
|
|
|
|
import { useMap } from "react-map-gl";
|
|
|
|
import { usePointSelection } from "../../stores/usePointSelection";
|
|
|
|
import { usePointSelection } from "../../stores/usePointSelection";
|
|
|
|
import { useFilters } from "../../stores/useFilters";
|
|
|
|
import { useFilters } from "../../stores/useFilters";
|
|
|
|
import { useClickedPoint } from "../../stores/useClickedPoint";
|
|
|
|
import { useClickedPointLocationId } from "../../stores/useClickedPointLocationId";
|
|
|
|
|
|
|
|
import scrollIntoView from "scroll-into-view-if-needed";
|
|
|
|
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
const columns = [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -69,24 +70,20 @@ const columns = [
|
|
|
|
|
|
|
|
|
|
|
|
const PAGE_SIZE = 30;
|
|
|
|
const PAGE_SIZE = 30;
|
|
|
|
|
|
|
|
|
|
|
|
export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
const useTableData = (page) => {
|
|
|
|
const { map } = useMap();
|
|
|
|
const [pageSize, setPageSize] = useState(PAGE_SIZE);
|
|
|
|
const tableRef = useRef(null);
|
|
|
|
|
|
|
|
const [page, setPage] = useState(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { filters } = useFilters();
|
|
|
|
const { filters } = useFilters();
|
|
|
|
const { prediction, status, categories } = filters;
|
|
|
|
const { prediction, status, categories } = filters;
|
|
|
|
const { include, selection, exclude } = usePointSelection();
|
|
|
|
const { selection } = usePointSelection();
|
|
|
|
const { point } = useClickedPoint();
|
|
|
|
const { clickedPointConfig } = useClickedPointLocationId();
|
|
|
|
|
|
|
|
const [finalData, setFinalData] = useState();
|
|
|
|
console.log(point);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { data } = useQuery(
|
|
|
|
const { data } = useQuery(
|
|
|
|
["table", page, filters],
|
|
|
|
["table", page, filters, selection],
|
|
|
|
async () => {
|
|
|
|
async () => {
|
|
|
|
const params = new URLSearchParams({
|
|
|
|
const params = new URLSearchParams({
|
|
|
|
page,
|
|
|
|
page,
|
|
|
|
page_size: PAGE_SIZE,
|
|
|
|
page_size: pageSize,
|
|
|
|
"prediction_current[]": prediction,
|
|
|
|
"prediction_current[]": prediction,
|
|
|
|
"status[]": status,
|
|
|
|
"status[]": status,
|
|
|
|
"categories[]": categories,
|
|
|
|
"categories[]": categories,
|
|
|
|
@ -103,6 +100,85 @@ export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
{ keepPreviousData: true }
|
|
|
|
{ keepPreviousData: true }
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
if (!data) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setFinalData(data);
|
|
|
|
|
|
|
|
}, [data]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [shouldLoadClickedPoint, setShouldLoadClickedPoint] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
if (!data || clickedPointConfig === null) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const clickedPoint = data.results.find(
|
|
|
|
|
|
|
|
(item) => item.location_id === clickedPointConfig.locationId
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (clickedPoint) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setShouldLoadClickedPoint(true);
|
|
|
|
|
|
|
|
}, [data, clickedPointConfig]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
|
|
data: remoteClickedPoint,
|
|
|
|
|
|
|
|
isInitialLoading,
|
|
|
|
|
|
|
|
isFetching,
|
|
|
|
|
|
|
|
} = useQuery(
|
|
|
|
|
|
|
|
["clicked-point", clickedPointConfig],
|
|
|
|
|
|
|
|
async () => {
|
|
|
|
|
|
|
|
const params = new URLSearchParams({
|
|
|
|
|
|
|
|
"location_ids[]": [clickedPointConfig.locationId],
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { data } = await api.get(
|
|
|
|
|
|
|
|
`/api/placement_points?${params.toString()}`
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
enabled: shouldLoadClickedPoint,
|
|
|
|
|
|
|
|
onSuccess: () => setShouldLoadClickedPoint(false),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
if (!remoteClickedPoint) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setPageSize((prevState) => prevState + 1);
|
|
|
|
|
|
|
|
setFinalData((prevState) => ({
|
|
|
|
|
|
|
|
...prevState,
|
|
|
|
|
|
|
|
count: prevState.count + 1,
|
|
|
|
|
|
|
|
results: [remoteClickedPoint.results[0], ...prevState.results],
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
}, [remoteClickedPoint]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
if (clickedPointConfig === null) {
|
|
|
|
|
|
|
|
setPageSize(PAGE_SIZE);
|
|
|
|
|
|
|
|
setFinalData(data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}, [clickedPointConfig]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
data: finalData,
|
|
|
|
|
|
|
|
pageSize,
|
|
|
|
|
|
|
|
isClickedPointLoading: isInitialLoading || isFetching,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
|
|
|
|
const { map } = useMap();
|
|
|
|
|
|
|
|
const tableRef = useRef(null);
|
|
|
|
|
|
|
|
const [page, setPage] = useState(1);
|
|
|
|
|
|
|
|
const { selection, include, exclude } = usePointSelection();
|
|
|
|
|
|
|
|
const { clickedPointConfig } = useClickedPointLocationId();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { data, pageSize, isClickedPointLoading } = useTableData(page);
|
|
|
|
|
|
|
|
|
|
|
|
const SCROLL = {
|
|
|
|
const SCROLL = {
|
|
|
|
y: `${height}px`,
|
|
|
|
y: `${height}px`,
|
|
|
|
x: "max-content",
|
|
|
|
x: "max-content",
|
|
|
|
@ -110,13 +186,23 @@ export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
|
|
|
|
|
|
|
|
const handlePageChange = useCallback((page) => setPage(page), []);
|
|
|
|
const handlePageChange = useCallback((page) => setPage(page), []);
|
|
|
|
|
|
|
|
|
|
|
|
const getSelectedRowKeys = () => {
|
|
|
|
const getSelectedRowKeys = useCallback(() => {
|
|
|
|
const ids = data?.results.map((item) => item.id) ?? [];
|
|
|
|
const ids = data?.results.map((item) => item.id) ?? [];
|
|
|
|
|
|
|
|
const clickedPoint = data?.results.find(
|
|
|
|
|
|
|
|
(item) => item.location_id === clickedPointConfig?.locationId
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const inExcludedList = (id) => selection.excluded.has(id);
|
|
|
|
|
|
|
|
const shouldNotSelect = (id) =>
|
|
|
|
|
|
|
|
id === clickedPoint?.id && clickedPointConfig?.shouldSelect === false;
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
return [
|
|
|
|
...ids.filter((id) => !selection.excluded.has(id)),
|
|
|
|
...ids.filter((id) => {
|
|
|
|
|
|
|
|
return !inExcludedList(id) && !shouldNotSelect(id);
|
|
|
|
|
|
|
|
}),
|
|
|
|
...selection.included,
|
|
|
|
...selection.included,
|
|
|
|
];
|
|
|
|
];
|
|
|
|
};
|
|
|
|
}, [data, clickedPointConfig, selection]);
|
|
|
|
|
|
|
|
|
|
|
|
const rowSelection = {
|
|
|
|
const rowSelection = {
|
|
|
|
selectedRowKeys: getSelectedRowKeys(),
|
|
|
|
selectedRowKeys: getSelectedRowKeys(),
|
|
|
|
@ -128,8 +214,18 @@ export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
exclude(id);
|
|
|
|
exclude(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
hideSelectAll: true,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
if (clickedPointConfig === null || isClickedPointLoading) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const row = document.querySelector(".scroll-row");
|
|
|
|
|
|
|
|
if (row) {
|
|
|
|
|
|
|
|
scrollIntoView(row, { behavior: "smooth" });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}, [clickedPointConfig, data]);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="w-screen">
|
|
|
|
<div className="w-screen">
|
|
|
|
<Collapse>
|
|
|
|
<Collapse>
|
|
|
|
@ -142,8 +238,7 @@ export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
locale={{ emptyText: <Empty description="Нет данных" /> }}
|
|
|
|
locale={{ emptyText: <Empty description="Нет данных" /> }}
|
|
|
|
// loading={isLoading}
|
|
|
|
// loading={isLoading}
|
|
|
|
pagination={{
|
|
|
|
pagination={{
|
|
|
|
pageSize: PAGE_SIZE,
|
|
|
|
pageSize,
|
|
|
|
hideOnSinglePage: true,
|
|
|
|
|
|
|
|
current: page,
|
|
|
|
current: page,
|
|
|
|
onChange: handlePageChange,
|
|
|
|
onChange: handlePageChange,
|
|
|
|
total: data?.count,
|
|
|
|
total: data?.count,
|
|
|
|
@ -172,6 +267,11 @@ export const Table = React.memo(({ height = 200 }) => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
rowSelection={rowSelection}
|
|
|
|
rowSelection={rowSelection}
|
|
|
|
|
|
|
|
rowClassName={(record) =>
|
|
|
|
|
|
|
|
record.location_id === clickedPointConfig?.locationId
|
|
|
|
|
|
|
|
? "scroll-row"
|
|
|
|
|
|
|
|
: ""
|
|
|
|
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</Collapse.Panel>
|
|
|
|
</Collapse.Panel>
|
|
|
|
</Collapse>
|
|
|
|
</Collapse>
|
|
|
|
|