refactored components
This commit is contained in:
@ -3,8 +3,7 @@ import 'ol/ol.css'
|
||||
import { Modify } from 'ol/interaction'
|
||||
import { ImageStatic, Vector as VectorSource } from 'ol/source'
|
||||
import Feature from 'ol/Feature'
|
||||
import { IRectCoords, SatelliteMapsProvider } from '../../interfaces/map'
|
||||
import { Extent, getCenter } from 'ol/extent'
|
||||
import { getCenter } from 'ol/extent'
|
||||
import { highlightStyleRed, highlightStyleYellow } from './MapStyles'
|
||||
import { customMapSource, googleMapsSatelliteSource, yandexMapsSatelliteSource } from './MapSources'
|
||||
import { Geometry, Point } from 'ol/geom'
|
||||
@ -14,33 +13,31 @@ import { addInteractions, getFeatureByEntityId, handleImageDrop, loadFeatures, p
|
||||
import useSWR, { SWRConfiguration } from 'swr'
|
||||
import { fetcher } from '../../http/axiosInstance'
|
||||
import { BASE_URL } from '../../constants'
|
||||
import { IconBoxMultiple, IconBoxPadding, IconChevronLeft, IconPlus, IconUpload, IconX, } from '@tabler/icons-react'
|
||||
import { ICitySettings, IDistrict, IFigure, ILine } from '../../interfaces/gis'
|
||||
import { IconBoxPadding, IconChevronLeft, } from '@tabler/icons-react'
|
||||
import { ICitySettings, IFigure, ILine } from '../../interfaces/gis'
|
||||
import axios from 'axios'
|
||||
import MapToolbar from './MapToolbar/MapToolbar'
|
||||
import MapStatusbar from './MapStatusbar/MapStatusbar'
|
||||
import { setAlignMode, setSatMapsProvider, setTypeRoles, useMapStore, setMapLabel, } from '../../store/map'
|
||||
import { setAlignMode, setTypeRoles, useMapStore, setMapLabel, } from '../../store/map'
|
||||
import { useThrottle } from '@uidotdev/usehooks'
|
||||
import ObjectTree from '../Tree/ObjectTree'
|
||||
import { setCurrentObjectId, setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../store/objects'
|
||||
import MapLayers from './MapLayers/MapLayers'
|
||||
import ObjectParameters from './ObjectParameters/ObjectParameters'
|
||||
import TabsPane, { ITabsPane } from './TabsPane/TabsPane'
|
||||
//import { useSearchParams } from 'react-router-dom'
|
||||
import GeoJSON from 'ol/format/GeoJSON'
|
||||
import MapLegend from './MapLegend/MapLegend'
|
||||
import GisService from '../../services/GisService'
|
||||
import MapMode from './MapMode'
|
||||
import { satMapsProviders, schemas } from '../../constants/map'
|
||||
import MapPrint from './MapPrint/MapPrint'
|
||||
import { Field, Menu, MenuButton, MenuList, MenuPopover, MenuTrigger, Combobox, Option, Button, Divider, Spinner, Portal, Dropdown, Tooltip, Drawer, DrawerHeader, DrawerBody, Text, Link, List } from '@fluentui/react-components'
|
||||
import { IRegion } from '../../interfaces/fuel'
|
||||
import { Combobox, Option, Button, Divider, Spinner, Portal, Tooltip, Drawer } from '@fluentui/react-components'
|
||||
import { useAppStore } from '../../store/app'
|
||||
import { getDistrictData, getRegionData, setDistrictsData, setRegionsData } from '../../store/regions'
|
||||
import { ArrowLeft24Regular } from '@fluentui/react-icons'
|
||||
import { setDistrictsData, setRegionsData } from '../../store/regions'
|
||||
import View from 'ol/View'
|
||||
import { Icon, Style } from 'ol/style'
|
||||
import { fromLonLat } from 'ol/proj'
|
||||
import MapRegionSelect from './MapRegionSelect/MapRegionSelect'
|
||||
import MapLayersSelect from './MapLayers/MapLayersSelect'
|
||||
import MapObjectSearch from './MapObjectSearch/MapObjectSearch'
|
||||
|
||||
const swrOptions: SWRConfiguration = {
|
||||
revalidateOnFocus: false
|
||||
@ -72,8 +69,7 @@ const MapComponent = ({
|
||||
const { selectedYear, currentObjectId, selectedRegion, selectedDistrict } = useObjectsStore().id[id]
|
||||
const {
|
||||
mode, map, currentTool, alignMode, satMapsProvider,
|
||||
selectedObjectType, file, measureDraw,
|
||||
polygonExtent, rectCoords, draw, snap, translate,
|
||||
selectedObjectType, measureDraw, draw, snap, translate,
|
||||
drawingLayerSource,
|
||||
satLayer, staticMapLayer, figuresLayer, linesLayer,
|
||||
regionsLayer, districtBoundLayer, districtsLayer,
|
||||
@ -275,13 +271,6 @@ const MapComponent = ({
|
||||
}
|
||||
}, [satMapsProvider, satLayer])
|
||||
|
||||
// Upload map overlay
|
||||
const submitOverlay = async (file: File | null, polygonExtent: Extent | undefined, rectCoords: IRectCoords | undefined) => {
|
||||
await GisService.uploadOverlay(file, polygonExtent, rectCoords).then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
|
||||
// const { data: nodes } = useSWR('/nodes/all', () => fetcher('/nodes/all', BASE_URL.ems), { revalidateOnFocus: false })
|
||||
|
||||
// useEffect(() => {
|
||||
@ -303,9 +292,6 @@ const MapComponent = ({
|
||||
// }
|
||||
// }, [nodes, nodeLayerSource])
|
||||
|
||||
const [searchObject, setSearchObject] = useState<string | undefined>("")
|
||||
const throttledSearchObject = useThrottle(searchObject, 500)
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedObjectType || !map) return
|
||||
|
||||
@ -367,12 +353,6 @@ const MapComponent = ({
|
||||
return res
|
||||
}), swrOptions)
|
||||
|
||||
const { data: searchData } = useSWR(
|
||||
throttledSearchObject !== "" && selectedDistrict && selectedYear ? `/general/search/objects?q=${throttledSearchObject}&id_city=${selectedDistrict}&year=${selectedYear}` : null,
|
||||
(url) => fetcher(url, BASE_URL.ems),
|
||||
swrOptions
|
||||
)
|
||||
|
||||
const { data: figuresData, isValidating: figuresValidating } = useSWR(
|
||||
selectedDistrict && selectedYear ? `/gis/figures/all?city_id=${selectedDistrict}&year=${selectedYear}&offset=0&limit=${10000}` : null,
|
||||
(url) => axios.get(url, {
|
||||
@ -609,214 +589,18 @@ const MapComponent = ({
|
||||
{active &&
|
||||
<Portal mountNode={document.querySelector('#header-portal')}>
|
||||
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||
<Combobox
|
||||
placeholder="Поиск"
|
||||
value={searchObject}
|
||||
onOptionSelect={(_ev, data) => {
|
||||
if (data.optionValue) {
|
||||
setCurrentObjectId(id, data.optionValue);
|
||||
setSearchObject(
|
||||
searchData?.find((item: any) => item.id_object.toString() === data.optionValue)?.value ?? ""
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setSearchObject(e.currentTarget.value); // free typing like Mantine's onChange
|
||||
}}
|
||||
clearable
|
||||
style={{ minWidth: 'auto' }}
|
||||
>
|
||||
{searchData
|
||||
? searchData.map((item: { value: string; id_object: string }) => (
|
||||
<Option key={item.id_object} value={item.id_object.toString()}>
|
||||
{item.value}
|
||||
</Option>
|
||||
))
|
||||
: null}
|
||||
</Combobox>
|
||||
<MapObjectSearch map_id={id} />
|
||||
|
||||
<Button icon={<IconBoxPadding />} appearance={alignMode ? 'primary' : 'transparent'} onClick={() => setAlignMode(id, !alignMode)} />
|
||||
|
||||
<Menu persistOnItemClick positioning={{ autoSize: true }}>
|
||||
<MenuTrigger disableButtonEnhancement>
|
||||
<MenuButton appearance='subtle' icon={<IconBoxMultiple />}>Слои</MenuButton>
|
||||
</MenuTrigger>
|
||||
|
||||
<MenuPopover>
|
||||
<MenuList style={{ padding: '1rem' }}>
|
||||
<Field>Настройка видимости слоёв</Field>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
|
||||
<Field label="Спутниковые снимки">
|
||||
<Dropdown
|
||||
value={satMapsProviders.find(provider => provider.value === satMapsProvider)?.label}
|
||||
selectedOptions={[satMapsProvider]}
|
||||
onOptionSelect={(_ev, data) => {
|
||||
if (data.optionValue) {
|
||||
setSatMapsProvider(id, data.optionValue as SatelliteMapsProvider);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{satMapsProviders.map((provider) => (
|
||||
<Option key={provider.value} text={provider.label} value={provider.value}>
|
||||
{provider.label}
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Field>
|
||||
</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
}}>
|
||||
<Button icon={<IconUpload />} appearance='transparent' onClick={() => submitOverlay(file, polygonExtent, rectCoords)} />
|
||||
|
||||
<Button icon={<IconPlus />} appearance='transparent' title='Добавить подложку' />
|
||||
</div>
|
||||
<MapLayers map={map} />
|
||||
</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
<MapLayersSelect map_id={id} />
|
||||
</div>
|
||||
</Portal >
|
||||
}
|
||||
|
||||
<div style={{ gridRow: '1 / span 1', display: 'grid', gridTemplateColumns: 'min-content auto', position: 'relative' }}>
|
||||
<div style={{ gridColumn: '1 / span 1', width: !selectedRegion || (!!selectedRegion && !selectedYear) ? '300px' : 'min-content', height: '100%', position: 'relative', display: 'flex', zIndex: '2' }}>
|
||||
<Drawer style={{ position: 'absolute', width: '300px', height: '100%', inset: 0, zIndex: 1 }} open={!selectedRegion || (!!selectedRegion && !selectedYear)} type='inline'>
|
||||
{!!selectedRegion && !selectedYear &&
|
||||
<DrawerHeader style={{ flexDirection: 'row' }}>
|
||||
<Button icon={<ArrowLeft24Regular />} appearance='subtle' onClick={() => {
|
||||
if (selectedDistrict) {
|
||||
setSelectedDistrict(id, null)
|
||||
districtSelect.getFeatures().clear()
|
||||
regionsLayer.setOpacity(1)
|
||||
} else {
|
||||
setSelectedRegion(id, null)
|
||||
regionSelect.getFeatures().clear()
|
||||
|
||||
if (map) {
|
||||
const extent = regionsLayer.getSource()?.getExtent()
|
||||
|
||||
if (extent) {
|
||||
map.getView().fit(fromExtent(extent), { duration: 100 })
|
||||
regionsLayer.setOpacity(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}} />
|
||||
|
||||
{selectedDistrict ?
|
||||
<Text weight='bold' size={500}>{getDistrictData(selectedDistrict)?.name}</Text>
|
||||
:
|
||||
<Text weight='bold' size={500}>{selectedRegion && getRegionData(selectedRegion)?.name}</Text>}
|
||||
|
||||
<Button appearance='subtle' style={{ marginLeft: 'auto' }} icon={<IconX />} onClick={() => {
|
||||
setSelectedYear(id, null)
|
||||
setSelectedDistrict(id, null)
|
||||
setSelectedRegion(id, null)
|
||||
|
||||
if (map) {
|
||||
const extent = regionsLayer.getSource()?.getExtent()
|
||||
|
||||
if (extent) {
|
||||
map.getView().fit(fromExtent(extent), { duration: 100 })
|
||||
regionsLayer.setOpacity(1)
|
||||
}
|
||||
}
|
||||
}} />
|
||||
</DrawerHeader>
|
||||
}
|
||||
|
||||
{!!selectedRegion && !selectedYear ?
|
||||
<DrawerBody>
|
||||
<div key={selectedRegion} style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
|
||||
{selectedDistrict ?
|
||||
selectedRegion && Object.entries(getRegionData(selectedRegion) as IRegion).map(([key, value]) => (
|
||||
<div key={key} style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<span>{key}</span>
|
||||
<span>{value}</span>
|
||||
</div>
|
||||
))
|
||||
:
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
<div>
|
||||
{selectedRegion && Object.entries(getRegionData(selectedRegion) as IRegion).map(([key, value]) => (
|
||||
<div key={key} style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<span>{key}</span>
|
||||
<span>{value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{districtsData && districtsData.map((district: IDistrict) => (
|
||||
<Link key={district.id} onClick={() => {
|
||||
setSelectedDistrict(id, district.id)
|
||||
map?.removeInteraction(districtSelect)
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
const feature = getFeatureByEntityId(district.id, districtsLayer)
|
||||
|
||||
if (feature) {
|
||||
districtSelect.getFeatures().push(feature)
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
districtSelect.getFeatures().clear()
|
||||
}}
|
||||
>{district.name}</Link>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
|
||||
{selectedDistrict &&
|
||||
<Field label="Схема" >
|
||||
<Dropdown
|
||||
style={{ minWidth: 'auto' }}
|
||||
value={selectedYear ? selectedYear.toString() : ""}
|
||||
selectedOptions={[selectedYear ? selectedYear.toString() : ""]}
|
||||
onOptionSelect={(_ev, data) => {
|
||||
if (data.optionValue) {
|
||||
setSelectedYear(id, Number(data.optionValue));
|
||||
} else {
|
||||
setSelectedYear(id, null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{schemas.map((el) => (
|
||||
<Option key={el} value={el} text={el}>
|
||||
{el}
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Field>
|
||||
}
|
||||
</div>
|
||||
</DrawerBody>
|
||||
:
|
||||
<DrawerBody>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
{regionsData && regionsData.map((region: IRegion) => (
|
||||
<Link key={region.id} onClick={() => {
|
||||
setSelectedRegion(id, region.id)
|
||||
map?.removeInteraction(regionSelect)
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
const feature = getFeatureByEntityId(region.id, regionsLayer)
|
||||
|
||||
if (feature) {
|
||||
regionSelect.getFeatures().push(feature)
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
regionSelect.getFeatures().clear()
|
||||
}}
|
||||
>{region.name}</Link>
|
||||
))}
|
||||
</div>
|
||||
</DrawerBody>
|
||||
}
|
||||
|
||||
</Drawer>
|
||||
<MapRegionSelect map_id={id} />
|
||||
</div>
|
||||
|
||||
<div ref={mapElement} id={id} key={id} style={{ gridColumn: '2 / span 1', position: 'relative', width: '100%', height: '100%', maxHeight: '100%', zIndex: '1', filter: colorScheme === 'dark' ? 'invert(100%) hue-rotate(180deg)' : 'unset' }} onDragOver={(e) => e.preventDefault()} onDrop={(e) => handleImageDrop(e, id)}>
|
||||
|
||||
67
client/src/components/map/MapLayers/MapLayersSelect.tsx
Normal file
67
client/src/components/map/MapLayers/MapLayersSelect.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
import { Button, Dropdown, Field, Menu, MenuButton, MenuList, MenuPopover, MenuTrigger, Option } from '@fluentui/react-components';
|
||||
import { IconBoxMultiple, IconPlus, IconUpload } from '@tabler/icons-react';
|
||||
import MapLayers from './MapLayers';
|
||||
import { setSatMapsProvider, useMapStore } from '../../../store/map';
|
||||
import { satMapsProviders } from '../../../constants/map';
|
||||
import { IRectCoords, SatelliteMapsProvider } from '../../../interfaces/map';
|
||||
import GisService from '../../../services/GisService';
|
||||
import { Extent } from 'ol/extent';
|
||||
|
||||
const MapLayersSelect = ({
|
||||
map_id
|
||||
}: {
|
||||
map_id: string
|
||||
}) => {
|
||||
const { map, satMapsProvider, file, polygonExtent, rectCoords } = useMapStore().id[map_id]
|
||||
|
||||
// Upload map overlay
|
||||
const submitOverlay = async (file: File | null, polygonExtent: Extent | undefined, rectCoords: IRectCoords | undefined) => {
|
||||
await GisService.uploadOverlay(file, polygonExtent, rectCoords).then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu persistOnItemClick positioning={{ autoSize: true }}>
|
||||
<MenuTrigger disableButtonEnhancement>
|
||||
<MenuButton appearance='subtle' icon={<IconBoxMultiple />}>Слои</MenuButton>
|
||||
</MenuTrigger>
|
||||
|
||||
<MenuPopover>
|
||||
<MenuList style={{ padding: '1rem' }}>
|
||||
<Field>Настройка видимости слоёв</Field>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
|
||||
<Field label="Спутниковые снимки">
|
||||
<Dropdown
|
||||
value={satMapsProviders.find(provider => provider.value === satMapsProvider)?.label}
|
||||
selectedOptions={[satMapsProvider]}
|
||||
onOptionSelect={(_ev, data) => {
|
||||
if (data.optionValue) {
|
||||
setSatMapsProvider(map_id, data.optionValue as SatelliteMapsProvider);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{satMapsProviders.map((provider) => (
|
||||
<Option key={provider.value} text={provider.label} value={provider.value}>
|
||||
{provider.label}
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Field>
|
||||
</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
}}>
|
||||
<Button icon={<IconUpload />} appearance='transparent' onClick={() => submitOverlay(file, polygonExtent, rectCoords)} />
|
||||
|
||||
<Button icon={<IconPlus />} appearance='transparent' title='Добавить подложку' />
|
||||
</div>
|
||||
<MapLayers map={map} />
|
||||
</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
|
||||
export default MapLayersSelect
|
||||
@ -0,0 +1,58 @@
|
||||
import { Combobox, Option } from '@fluentui/react-components';
|
||||
import { useState } from 'react'
|
||||
import { setCurrentObjectId, useObjectsStore } from '../../../store/objects';
|
||||
import useSWR, { SWRConfiguration } from 'swr';
|
||||
import { useThrottle } from '@uidotdev/usehooks';
|
||||
import { BASE_URL } from '../../../constants';
|
||||
import { fetcher } from '../../../http/axiosInstanceNest';
|
||||
|
||||
const swrOptions: SWRConfiguration = {
|
||||
revalidateOnFocus: false
|
||||
}
|
||||
|
||||
const MapObjectSearch = ({
|
||||
map_id
|
||||
}: {
|
||||
map_id: string
|
||||
}) => {
|
||||
const [searchObject, setSearchObject] = useState<string | undefined>("")
|
||||
const throttledSearchObject = useThrottle(searchObject, 500)
|
||||
|
||||
const { selectedYear, selectedDistrict } = useObjectsStore().id[map_id]
|
||||
|
||||
const { data: searchData } = useSWR(
|
||||
throttledSearchObject !== "" && selectedDistrict && selectedYear ? `/general/search/objects?q=${throttledSearchObject}&id_city=${selectedDistrict}&year=${selectedYear}` : null,
|
||||
(url) => fetcher(url, BASE_URL.ems),
|
||||
swrOptions
|
||||
)
|
||||
|
||||
return (
|
||||
<Combobox
|
||||
placeholder="Поиск"
|
||||
value={searchObject}
|
||||
onOptionSelect={(_ev, data) => {
|
||||
if (data.optionValue) {
|
||||
setCurrentObjectId(map_id, data.optionValue);
|
||||
setSearchObject(
|
||||
searchData?.find((item: any) => item.id_object.toString() === data.optionValue)?.value ?? ""
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setSearchObject(e.currentTarget.value); // free typing like Mantine's onChange
|
||||
}}
|
||||
clearable
|
||||
style={{ minWidth: 'auto' }}
|
||||
>
|
||||
{searchData
|
||||
? searchData.map((item: { value: string; id_object: string }) => (
|
||||
<Option key={item.id_object} value={item.id_object.toString()}>
|
||||
{item.value}
|
||||
</Option>
|
||||
))
|
||||
: null}
|
||||
</Combobox>
|
||||
)
|
||||
}
|
||||
|
||||
export default MapObjectSearch
|
||||
172
client/src/components/map/MapRegionSelect/MapRegionSelect.tsx
Normal file
172
client/src/components/map/MapRegionSelect/MapRegionSelect.tsx
Normal file
@ -0,0 +1,172 @@
|
||||
import { Button, Drawer, DrawerBody, DrawerHeader, Dropdown, Field, Link, Option, Text } from '@fluentui/react-components'
|
||||
import { ArrowLeft24Regular } from '@fluentui/react-icons'
|
||||
import { setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../../store/objects'
|
||||
import { useMapStore } from '../../../store/map'
|
||||
import { fromExtent } from 'ol/geom/Polygon'
|
||||
import { getDistrictData, getRegionData, setDistrictsData, useRegionsStore } from '../../../store/regions'
|
||||
import { IconX } from '@tabler/icons-react'
|
||||
import { IDistrict, IRegion } from '../../../interfaces/gis'
|
||||
import { getFeatureByEntityId } from '../mapUtils'
|
||||
import useSWR, { SWRConfiguration } from 'swr'
|
||||
import { fetcher } from '../../../http/axiosInstanceNest'
|
||||
import { BASE_URL } from '../../../constants'
|
||||
import { schemas } from '../../../constants/map'
|
||||
|
||||
const swrOptions: SWRConfiguration = {
|
||||
revalidateOnFocus: false
|
||||
}
|
||||
|
||||
const MapRegionSelect = ({
|
||||
map_id
|
||||
}: {
|
||||
map_id: string
|
||||
}) => {
|
||||
const { map, districtSelect, regionsLayer, regionSelect, districtsLayer } = useMapStore().id[map_id]
|
||||
const { selectedRegion, selectedYear, selectedDistrict } = useObjectsStore().id[map_id]
|
||||
const { regionsData } = useRegionsStore()
|
||||
|
||||
const { data: districtsData } = useSWR(selectedRegion ? `/general/districts/?region_id=${selectedRegion}` : null, (url) => fetcher(url, BASE_URL.ems).then(res => {
|
||||
setDistrictsData(res)
|
||||
return res
|
||||
}), swrOptions)
|
||||
|
||||
return (
|
||||
<Drawer style={{ position: 'absolute', width: '300px', height: '100%', inset: 0, zIndex: 1 }} open={!selectedRegion || (!!selectedRegion && !selectedYear)} type='inline'>
|
||||
{!!selectedRegion && !selectedYear &&
|
||||
<DrawerHeader style={{ flexDirection: 'row' }}>
|
||||
<Button icon={<ArrowLeft24Regular />} appearance='subtle' onClick={() => {
|
||||
if (selectedDistrict) {
|
||||
setSelectedDistrict(map_id, null)
|
||||
districtSelect.getFeatures().clear()
|
||||
regionsLayer.setOpacity(1)
|
||||
} else {
|
||||
setSelectedRegion(map_id, null)
|
||||
regionSelect.getFeatures().clear()
|
||||
|
||||
if (map) {
|
||||
const extent = regionsLayer.getSource()?.getExtent()
|
||||
|
||||
if (extent) {
|
||||
map.getView().fit(fromExtent(extent), { duration: 100 })
|
||||
regionsLayer.setOpacity(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}} />
|
||||
|
||||
{selectedDistrict ?
|
||||
<Text weight='bold' size={500}>{getDistrictData(selectedDistrict)?.name}</Text>
|
||||
:
|
||||
<Text weight='bold' size={500}>{selectedRegion && getRegionData(selectedRegion)?.name}</Text>}
|
||||
|
||||
<Button appearance='subtle' style={{ marginLeft: 'auto' }} icon={<IconX />} onClick={() => {
|
||||
setSelectedYear(map_id, null)
|
||||
setSelectedDistrict(map_id, null)
|
||||
setSelectedRegion(map_id, null)
|
||||
|
||||
if (map) {
|
||||
const extent = regionsLayer.getSource()?.getExtent()
|
||||
|
||||
if (extent) {
|
||||
map.getView().fit(fromExtent(extent), { duration: 100 })
|
||||
regionsLayer.setOpacity(1)
|
||||
}
|
||||
}
|
||||
}} />
|
||||
</DrawerHeader>
|
||||
}
|
||||
|
||||
{!!selectedRegion && !selectedYear ?
|
||||
<DrawerBody>
|
||||
<div key={selectedRegion} style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
|
||||
{selectedDistrict ?
|
||||
selectedRegion && Object.entries(getRegionData(selectedRegion) as IRegion).map(([key, value]) => (
|
||||
<div key={key} style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<span>{key}</span>
|
||||
<span>{value}</span>
|
||||
</div>
|
||||
))
|
||||
:
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
<div>
|
||||
{selectedRegion && Object.entries(getRegionData(selectedRegion) as IRegion).map(([key, value]) => (
|
||||
<div key={key} style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<span>{key}</span>
|
||||
<span>{value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{districtsData && districtsData.map((district: IDistrict) => (
|
||||
<Link key={district.id} onClick={() => {
|
||||
setSelectedDistrict(map_id, district.id)
|
||||
map?.removeInteraction(districtSelect)
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
const feature = getFeatureByEntityId(district.id, districtsLayer)
|
||||
|
||||
if (feature) {
|
||||
districtSelect.getFeatures().push(feature)
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
districtSelect.getFeatures().clear()
|
||||
}}
|
||||
>{district.name}</Link>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
|
||||
{selectedDistrict &&
|
||||
<Field label="Схема" >
|
||||
<Dropdown
|
||||
style={{ minWidth: 'auto' }}
|
||||
value={selectedYear ? selectedYear.toString() : ""}
|
||||
selectedOptions={[selectedYear ? selectedYear.toString() : ""]}
|
||||
onOptionSelect={(_ev, data) => {
|
||||
if (data.optionValue) {
|
||||
setSelectedYear(map_id, Number(data.optionValue));
|
||||
} else {
|
||||
setSelectedYear(map_id, null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{schemas.map((el) => (
|
||||
<Option key={el} value={el} text={el}>
|
||||
{el}
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Field>
|
||||
}
|
||||
</div>
|
||||
</DrawerBody>
|
||||
:
|
||||
<DrawerBody>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
{regionsData && regionsData.map((region: IRegion) => (
|
||||
<Link key={region.id} onClick={() => {
|
||||
setSelectedRegion(map_id, region.id)
|
||||
map?.removeInteraction(regionSelect)
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
const feature = getFeatureByEntityId(region.id, regionsLayer)
|
||||
|
||||
if (feature) {
|
||||
regionSelect.getFeatures().push(feature)
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
regionSelect.getFeatures().clear()
|
||||
}}
|
||||
>{region.name}</Link>
|
||||
))}
|
||||
</div>
|
||||
</DrawerBody>
|
||||
}
|
||||
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default MapRegionSelect
|
||||
Reference in New Issue
Block a user