diff --git a/src/context.ts b/src/context.ts index 3d8cf90..c638ae6 100644 --- a/src/context.ts +++ b/src/context.ts @@ -3,6 +3,8 @@ import { createContext, useContext, useEffect } from 'react' import { LayoutPortalProps } from '@components/LayoutPortal' import { DepositDto, UserTokenDto, WellDto } from '@api' +/** Контекст текущего месторождения */ +export const DepositContext = createContext(null) /** Контекст текущей скважины */ export const WellContext = createContext<[WellDto, (well: WellDto) => void]>([{}, () => {}]) /** Контекст текущего корневого пути */ @@ -19,10 +21,17 @@ export const DepositListContext = createContext([]) /** * Получить текущую скважину * - * @returns Текущая скважина, либо `null` + * @returns Текущая скважина, либо пустой объект */ export const useWell = () => useContext(WellContext) +/** + * Получить текущее месторождение + * + * @returns Текущее месторождение, либо `null` + */ +export const useDeposit = () => useContext(DepositContext) + /** * Получить текущий корневой путь * diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx deleted file mode 100755 index 8d37569..0000000 --- a/src/pages/Deposit.jsx +++ /dev/null @@ -1,106 +0,0 @@ -import { useEffect, memo, useMemo, useCallback } from 'react' -import { Link, useLocation } from 'react-router-dom' -import { Map, Overlay } from 'pigeon-maps' -import { Popover, Badge } from 'antd' - -import { useDepositList, useLayoutProps } from '@asb/context' -import { PointerIcon } from '@components/icons' -import { FastRunMenu } from '@components/FastRunMenu' -import { limitValue, withPermissions } from '@utils' - -import '@styles/index.css' - -const zoomLimit = limitValue(5, 15) - -const calcViewParams = (clusters) => { - if ((clusters?.length ?? 0) <= 0) - return { center: [60.81226, 70.0562], zoom: 5 } - - const center = clusters.reduce((sum, cluster) => { - sum[0] += cluster.latitude - sum[1] += cluster.longitude - return sum - }, [0, 0]).map((elm) => elm / clusters.length) - - const maxDeg = clusters.reduce((max, cluster) => { - const dLatitude = Math.abs(center[0] - cluster.latitude) - const dLongitude = Math.abs(center[1] - cluster.longitude) - return Math.max(Math.max(dLatitude, dLongitude), max) - }, 0) - - // zoom max = 20 (too close) - // zoom min = 1 (mega far) - // 4 - full Russia (161.6 deg) - // 13.5 - Khanty-Mansiysk - const zoom = zoomLimit(5 + 5 / (maxDeg + 0.5)) - - return { center, zoom } -} - -const Deposit = memo(() => { - const deposits = useDepositList() - const setLayoutProps = useLayoutProps() - const location = useLocation() - - const makeDepositLinks = useCallback((clusters) => ( -
- {clusters.map(cluster => ( - -
{cluster.caption}
- - ))} -
- ), [location.pathname]) - - const viewParams = useMemo(() => calcViewParams(deposits), [deposits]) - - useEffect(() => { - const hasId = location.pathname.length > '/deposit/'.length - - const selectorProps = { - expand: hasId ? [location.pathname] : true, - current: hasId ? location.pathname : undefined, - } - - setLayoutProps({ - sheet: false, - showSelector: true, - selectorProps, - title: 'Месторождение', - }) - }, [setLayoutProps, location.pathname]) - - return ( - <> - -
- - {deposits.map(deposit => { - const anchor = [deposit.latitude, deposit.longitude] - const links = makeDepositLinks(deposit.clusters) - - return ( - - -
- - - -
-
-
- ) - })} -
-
- - ) -}) - -export default withPermissions(Deposit, ['Cluster.get']) diff --git a/src/pages/Deposit/DepositNavigationMenu.jsx b/src/pages/Deposit/DepositNavigationMenu.jsx new file mode 100644 index 0000000..304f062 --- /dev/null +++ b/src/pages/Deposit/DepositNavigationMenu.jsx @@ -0,0 +1,23 @@ +import { memo } from 'react' +import { + HeatMapOutlined, +} from '@ant-design/icons' + +import { makeItem, PrivateMenu } from '@components/PrivateMenu' + +export const menuItems = [ + makeItem('Карта', 'map', [], ), +] + +export const DepositNavigationMenu = memo((props) => ( + +)) + +export default DepositNavigationMenu diff --git a/src/pages/Deposit/Map.jsx b/src/pages/Deposit/Map.jsx new file mode 100644 index 0000000..b849dae --- /dev/null +++ b/src/pages/Deposit/Map.jsx @@ -0,0 +1,85 @@ +import { memo, useMemo, useCallback } from 'react' +import { Link, useLocation } from 'react-router-dom' +import { Map as PigeonMap, Overlay } from 'pigeon-maps' +import { Popover, Badge } from 'antd' + +import { useDepositList } from '@asb/context' +import { PointerIcon } from '@components/icons' +import { limitValue, withPermissions } from '@utils' + +import '@styles/index.css' + +const zoomLimit = limitValue(5, 15) + +const calcViewParams = (clusters) => { + if ((clusters?.length ?? 0) <= 0) + return { center: [60.81226, 70.0562], zoom: 5 } + + const center = clusters.reduce((sum, cluster) => { + sum[0] += cluster.latitude + sum[1] += cluster.longitude + return sum + }, [0, 0]).map((elm) => elm / clusters.length) + + const maxDeg = clusters.reduce((max, cluster) => { + const dLatitude = Math.abs(center[0] - cluster.latitude) + const dLongitude = Math.abs(center[1] - cluster.longitude) + return Math.max(Math.max(dLatitude, dLongitude), max) + }, 0) + + // zoom max = 20 (too close) + // zoom min = 1 (mega far) + // 4 - full Russia (161.6 deg) + // 13.5 - Khanty-Mansiysk + const zoom = zoomLimit(5 + 5 / (maxDeg + 0.5)) + + return { center, zoom } +} + +const Map = memo(() => { + const deposits = useDepositList() + const location = useLocation() + + const makeDepositLinks = useCallback((clusters) => ( +
+ {clusters.map(cluster => ( + +
{cluster.caption}
+ + ))} +
+ ), [location.pathname]) + + const viewParams = useMemo(() => calcViewParams(deposits), [deposits]) + + return ( +
+ + {deposits.map(deposit => { + const anchor = [deposit.latitude, deposit.longitude] + const links = makeDepositLinks(deposit.clusters) + + return ( + + +
+ + + +
+
+
+ ) + })} +
+
+ ) +}) + +export default withPermissions(Map, ['Cluster.get']) diff --git a/src/pages/Deposit/index.jsx b/src/pages/Deposit/index.jsx new file mode 100644 index 0000000..b342af2 --- /dev/null +++ b/src/pages/Deposit/index.jsx @@ -0,0 +1,64 @@ +import { Navigate, Route, Routes, useLocation, useParams } from 'react-router-dom' +import { lazy, memo, useEffect, useMemo } from 'react' + +import { DepositContext, RootPathContext, useDepositList, useLayoutProps, useRootPath } from '@asb/context' +import FastRunMenu from '@components/FastRunMenu' +import { NoAccessComponent, withPermissions } from '@utils' + +const Map = lazy(() => import('./Map')) +const DepositNavigationMenu = lazy(() => import('./DepositNavigationMenu')) + +const Deposit = memo(() => { + const { '*': param } = useParams() + const location = useLocation() + + const setLayoutProps = useLayoutProps() + const deposits = useDepositList() + + const idDeposit = useMemo(() => { + const result = /^([^\/#?]+)/.exec(param) + return result && result[1] !== 'null' ? Number(result[1]) : null + }, [param]) + + const deposit = useMemo(() => deposits.find((deposit) => deposit.id === idDeposit) || null, [deposits, idDeposit]) + + const root = useRootPath() + const rootPath = useMemo(() => `${root}/deposit`, [root]) + + useEffect(() => { + const hasId = location.pathname.length > '/deposit/'.length + + const selectorProps = { + expand: hasId ? [location.pathname] : true, + current: hasId ? location.pathname : undefined, + } + + setLayoutProps({ + sheet: false, + sider: , + showSelector: true, + selectorProps, + title: 'Месторождение', + }) + }, [setLayoutProps, location.pathname, deposit]) + + return ( + + + + + } /> + + + } /> + } /> + + } /> + + + + + ) +}) + +export default withPermissions(Deposit, [])