dev
Platon Yasev 3 years ago
parent 5313a8f5dd
commit f0648bcaea

@ -17,6 +17,7 @@
"antd": "^4.23.6",
"axios": "^1.1.3",
"immer": "^9.0.16",
"lodash.debounce": "^4.0.8",
"mapbox-gl": "npm:empty-npm-package@1.0.0",
"maplibre-gl": "^2.4.0",
"nanostores": "^0.7.3",

@ -1,15 +1,17 @@
import maplibregl from "maplibre-gl";
import Map from "react-map-gl";
import { useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { Sidebar } from "../modules/Sidebar/Sidebar";
import { Layers } from "./Layers";
import { MapPopup } from "./Popup";
import { Basemap } from "./Basemap";
import { Legend } from "../modules/Sidebar/Legend";
import { SignOut } from "../SignOut";
import debounce from "lodash.debounce";
export const MapComponent = () => {
const mapRef = useRef(null);
const mapContainerRef = useRef(null);
const [clickedFeature, setClickedFeature] = useState(null);
const [popupCoordinates, setPopupCoordinates] = useState(null);
@ -57,42 +59,59 @@ export const MapComponent = () => {
mapRef.current.getCanvas().style.cursor = "";
};
useEffect(() => {
const resizeObserver = new ResizeObserver(
debounce(() => {
mapRef?.current?.resize();
}, 16)
);
if (mapContainerRef.current) {
resizeObserver.observe(mapContainerRef.current);
}
return () => {
resizeObserver.disconnect();
};
}, [mapContainerRef.current]);
return (
<Map
mapLib={maplibregl}
// mapStyle={`https://api.maptiler.com/maps/voyager/style.json?key=${MAP_TILER_KEY}`}
style={{ width: "100vw", height: "100vh" }}
initialViewState={{
latitude: 55.7558,
longitude: 37.6173,
zoom: 9,
}}
dragRotate={false}
ref={mapRef}
interactiveLayerIds={["point3", "point4", "point5"]}
onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{clickedFeature && popupCoordinates && (
<MapPopup
lat={popupCoordinates[1]}
lng={popupCoordinates[0]}
feature={clickedFeature}
onClose={() => {
setPopupCoordinates(null);
setClickedFeature(null);
}}
/>
)}
<div ref={mapContainerRef} className="w-full flex-1">
<Map
mapLib={maplibregl}
// mapStyle={`https://api.maptiler.com/maps/voyager/style.json?key=${MAP_TILER_KEY}`}
// style={{ width: "100%", height: "100%" }}
initialViewState={{
latitude: 55.7558,
longitude: 37.6173,
zoom: 9,
}}
dragRotate={false}
ref={mapRef}
interactiveLayerIds={["point3", "point4", "point5"]}
onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{clickedFeature && popupCoordinates && (
<MapPopup
lat={popupCoordinates[1]}
lng={popupCoordinates[0]}
feature={clickedFeature}
onClose={() => {
setPopupCoordinates(null);
setClickedFeature(null);
}}
/>
)}
<Basemap />
<Layers />
<Basemap />
<Layers />
<Sidebar />
<Sidebar />
<Legend />
<SignOut />
</Map>
<Legend />
<SignOut />
</Map>
</div>
);
};

@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;
#root {
@apply h-screen w-screen flex flex-col overflow-hidden;
}
.mapboxgl-popup,
.maplibregl-popup {
@apply max-w-[400px] min-w-[250px];
@ -76,6 +80,17 @@
width: 100% !important;
}
::-webkit-scrollbar {
width: 12px;
}
::-webkit-scrollbar-thumb {
border: 4px solid rgba(0, 0, 0, 0);
background-clip: padding-box;
border-radius: 9999px;
background-color: #e2e2e3;
}
/* Works on Firefox*/
* {
scrollbar-width: thin;
@ -83,18 +98,18 @@
}
/* Works on Chrome and Safari */
*::-webkit-scrollbar {
@apply h-[2px] w-[4px];
}
/**::-webkit-scrollbar {*/
/* @apply h-[2px] w-[4px];*/
/*}*/
*::-webkit-scrollbar-thumb {
@apply rounded-xl border border-solid border-transparent bg-grey-light;
}
/**::-webkit-scrollbar-thumb {*/
/* @apply rounded-xl border border-solid border-transparent bg-grey-light;*/
/*}*/
*::-webkit-scrollbar-track {
@apply rounded-xl bg-transparent;
}
/**::-webkit-scrollbar-track {*/
/* @apply rounded-xl bg-transparent;*/
/*}*/
*::-webkit-scrollbar-corner {
@apply hidden;
}
/**::-webkit-scrollbar-corner {*/
/* @apply hidden;*/
/*}*/

@ -29,22 +29,6 @@ export function Legend() {
</div>
))}
</div>
<Title
text={"Востребованность постамата"}
className={"mb-1 mt-3 text-center"}
/>
<div
className={"w-full h-[10px] rounded-xl"}
style={{
background:
"linear-gradient(to right, rgba(204,34,34,0.5), rgba(255,221,52,0.5), rgba(30,131,42,0.5))",
}}
/>
<div className={"w-full flex justify-between"}>
<span>мин</span>
<span>макс</span>
</div>
</div>
);
}

@ -0,0 +1,44 @@
.ant-collapse-content-box {
padding: 0 !important;
}
.ant-table-body {
@apply max-w-[100vw];
}
.table__wrapper .ant-table-row {
cursor: pointer;
}
.table__title {
padding: 0 1rem;
display: flex;
align-items: baseline;
margin-bottom: 0;
}
.title__content {
font-size: 16px;
font-weight: 600;
flex-grow: 1;
display: flex;
column-gap: 12px;
align-items: center;
}
.table__badge {
background-color: rgba(51, 51, 51, 0.05);
}
.ant-table-pagination.ant-pagination {
margin: 0;
}
.ant-table.ant-table-small .ant-table-title,
.ant-table.ant-table-small .ant-table-footer,
.ant-table.ant-table-small .ant-table-thead > tr > th,
.ant-table.ant-table-small .ant-table-tbody > tr > td,
.ant-table.ant-table-small tfoot > tr > th,
.ant-table.ant-table-small tfoot > tr > td {
padding: 4px;
}

@ -0,0 +1,138 @@
import React, { useRef } from "react";
import { Collapse, Empty, Table as AntdTable } from "antd";
import "./Table.css";
const columns = [
{
title: "Категория",
dataIndex: "category",
key: "category",
},
{
title: "Статус",
dataIndex: "status",
key: "status",
},
{
title: "Прогноз",
dataIndex: "predict",
key: "predict",
},
{
title: "Факт",
dataIndex: "fact",
key: "fact",
},
{
title: "Зрелость",
dataIndex: "age",
key: "age",
},
];
const data = [
{
id: "1",
category: "Жилой дом",
status: "Работающий",
predict: 80,
fact: 50,
age: 6,
},
{
id: "2",
category: "МФЦ",
status: "Не работает",
predict: 100,
fact: undefined,
age: 0,
},
{
id: "3",
category: "Библиотека",
status: "На рассмотрении",
predict: 80,
fact: undefined,
age: 0,
},
{
id: "4",
category: "Жилой дом",
status: "Работающий",
predict: 80,
fact: 50,
age: 6,
},
{
id: "5",
category: "МФЦ",
status: "Не работает",
predict: 100,
fact: undefined,
age: 0,
},
{
id: "6",
category: "Библиотека",
status: "На рассмотрении",
predict: 80,
fact: undefined,
age: 0,
},
{
id: "7",
category: "Жилой дом",
status: "Работающий",
predict: 80,
fact: 50,
age: 6,
},
{
id: "8",
category: "МФЦ",
status: "Не работает",
predict: 100,
fact: undefined,
age: 0,
},
{
id: "9",
category: "Библиотека",
status: "На рассмотрении",
predict: 80,
fact: undefined,
age: 0,
},
];
export const Table = React.memo(({ height = 200 }) => {
const tableRef = useRef(null);
const SCROLL = {
y: `${height}px`,
x: "max-content",
};
return (
<div className="w-screen">
<Collapse>
<Collapse.Panel key="1" header="Таблица атрибутов">
<AntdTable
ref={tableRef}
className="table"
size="small"
// rowSelection={rowSelection}
locale={{ emptyText: <Empty description="Нет данных" /> }}
// loading={isLoading}
pagination={false}
dataSource={data}
columns={columns}
rowKey="id"
scroll={SCROLL}
sticky={true}
/>
</Collapse.Panel>
</Collapse>
</div>
);
});

@ -1,10 +1,12 @@
import { WithAuth } from "../WithAuth";
import { MapComponent } from "../Map/MapComponent";
import { Table } from "../modules/Table/Table";
export function MapPage() {
return (
<WithAuth>
<MapComponent />
<Table />
</WithAuth>
);
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save