You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.5 KiB
119 lines
3.5 KiB
import React, { useEffect } from "react";
|
|
import { Collapse, Empty, Table as AntdTable } from "antd";
|
|
import "./Table.css";
|
|
import parse from "wellknown";
|
|
import { useMap } from "react-map-gl";
|
|
import { useClickedPointConfig } from "../../stores/useClickedPointConfig";
|
|
import scrollIntoView from "scroll-into-view-if-needed";
|
|
import { twMerge } from "tailwind-merge";
|
|
import { HeaderWrapper } from "./HeaderWrapper";
|
|
import { useTable } from "../../stores/useTable";
|
|
import { usePopup } from "../../stores/usePopup.js";
|
|
|
|
export const Table = React.memo(
|
|
({
|
|
data,
|
|
pageSize,
|
|
isClickedPointLoading,
|
|
page,
|
|
onPageChange,
|
|
columns,
|
|
header,
|
|
fullWidth,
|
|
loading,
|
|
onChange
|
|
}) => {
|
|
const { clickedPointConfig, setClickedPointConfig } =
|
|
useClickedPointConfig();
|
|
const { map } = useMap();
|
|
const { tableState, toggleOpened } = useTable();
|
|
const { setPopup } = usePopup();
|
|
|
|
const SCROLL = {
|
|
y: tableState.fullScreen ? "calc(100vh - 136px)" : "200px",
|
|
x: "max-content",
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (clickedPointConfig === null || isClickedPointLoading) return;
|
|
|
|
const row = document.querySelector(".scroll-row");
|
|
if (row) {
|
|
scrollIntoView(row, { behavior: "smooth" });
|
|
}
|
|
}, [clickedPointConfig, data]);
|
|
|
|
return (
|
|
<Collapse
|
|
bordered={false}
|
|
onChange={toggleOpened}
|
|
activeKey={tableState.isOpened ? "opened" : null}
|
|
>
|
|
<Collapse.Panel
|
|
key={"opened"}
|
|
header={header ? header : <HeaderWrapper />}
|
|
collapsible={tableState.fullScreen ? "disabled" : undefined}
|
|
>
|
|
<AntdTable
|
|
size="small"
|
|
className={twMerge(
|
|
"table__wrapper",
|
|
tableState.fullScreen && "table__wrapper__fullScreen"
|
|
)}
|
|
locale={{ emptyText: <Empty description="No data" /> }}
|
|
pagination={{
|
|
pageSize,
|
|
current: page,
|
|
onChange: onPageChange,
|
|
total: data?.count,
|
|
showSizeChanger: false,
|
|
position: "bottomCenter",
|
|
}}
|
|
showHeader={data?.results && data.results.length > 0}
|
|
dataSource={data?.results}
|
|
columns={columns}
|
|
onChange={onChange}
|
|
rowKey="id"
|
|
scroll={SCROLL}
|
|
sticky={true}
|
|
onRow={(record) => {
|
|
return {
|
|
onClick: () => {
|
|
const geometry = parse(record.geometry);
|
|
map.flyTo({
|
|
center: [geometry.coordinates[0], geometry.coordinates[1]],
|
|
zoom: 13,
|
|
essential: true,
|
|
});
|
|
|
|
const feature = {
|
|
properties: record,
|
|
};
|
|
|
|
setPopup({
|
|
features: [feature],
|
|
coordinates: geometry.coordinates,
|
|
});
|
|
|
|
setClickedPointConfig(
|
|
record.id,
|
|
rowSelection?.selectedRowKeys.includes(record.id)
|
|
);
|
|
},
|
|
};
|
|
}}
|
|
rowClassName={(record) =>
|
|
twMerge(
|
|
"cursor-pointer",
|
|
record.id === clickedPointConfig?.id && "scroll-row"
|
|
)
|
|
}
|
|
data-fullwidth={fullWidth}
|
|
loading={loading}
|
|
/>
|
|
</Collapse.Panel>
|
|
</Collapse>
|
|
);
|
|
}
|
|
);
|