Добавлено сворачивание месторождений кроме выбранного в селекторе скважин на странице месторождений

This commit is contained in:
goodmice 2022-10-03 21:35:26 +05:00
parent 34c9b81e77
commit 8db523b6de
No known key found for this signature in database
GPG Key ID: 63EA771203189CF1
3 changed files with 55 additions and 42 deletions

View File

@ -1,20 +1,20 @@
import { memo, ReactNode } from 'react'
import { Key, memo, ReactNode } from 'react'
import { Layout, LayoutProps } from 'antd'
import PageHeader from '@components/PageHeader'
import WellTreeSelector from '@components/selectors/WellTreeSelector'
import { WellTreeSelector, WellTreeSelectorProps } from '@components/selectors/WellTreeSelector'
import { wrapPrivateComponent } from '@utils'
export type LayoutPortalProps = LayoutProps & {
title?: ReactNode
noSheet?: boolean
showSelector?: boolean
selector?: WellTreeSelectorProps
}
const _LayoutPortal = memo<LayoutPortalProps>(({ title, noSheet, showSelector, ...props }) => (
const _LayoutPortal = memo<LayoutPortalProps>(({ title, noSheet, selector, ...props }) => (
<Layout.Content>
<PageHeader title={title}>
<WellTreeSelector show={showSelector} />
<WellTreeSelector {...selector} />
</PageHeader>
<Layout>
{noSheet ? props.children : (

View File

@ -1,6 +1,5 @@
import { Button, Drawer, Skeleton, Tree, TreeProps, Typography } from 'antd'
import { DefaultValueType } from 'rc-tree-select/lib/interface'
import { useState, useEffect, ReactNode, useCallback, memo, Key } from 'react'
import { Button, Drawer, Skeleton, Tree, TreeDataNode, TreeProps, Typography } from 'antd'
import { useState, useEffect, useCallback, memo, Key } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import { WellIcon, WellIconState } from '@components/icons'
@ -17,26 +16,18 @@ export const getWellState = (idState?: number): WellIconState => idState === 1 ?
export const checkIsWellOnline = (lastTelemetryDate: unknown): boolean =>
isRawDate(lastTelemetryDate) && (Date.now() - +new Date(lastTelemetryDate) < 600_000)
export type TreeNodeData = {
title?: string | null
key?: string
value?: DefaultValueType
icon?: ReactNode
children?: TreeNodeData[]
}
const getKeyByUrl = (url?: string): [Key | null, string | null] => {
const result = url?.match(/^\/([^\/]+)\/([^\/?]+)/) // pattern "/:type/:id"
if (!result) return [null, null]
return [result[0], result[1]]
}
const getLabel = (wellsTree: TreeNodeData[], value?: string): string | undefined => {
const getLabel = (wellsTree: TreeDataNode[], value?: string): string | undefined => {
const [url, type] = getKeyByUrl(value)
if (!url) return
let deposit: TreeNodeData | undefined
let cluster: TreeNodeData | undefined
let well: TreeNodeData | undefined
let deposit: TreeDataNode | undefined
let cluster: TreeDataNode | undefined
let well: TreeDataNode | undefined
switch (type) {
case 'deposit':
deposit = wellsTree.find((deposit) => deposit.key === url)
@ -46,7 +37,7 @@ const getLabel = (wellsTree: TreeNodeData[], value?: string): string | undefined
case 'cluster':
deposit = wellsTree.find((deposit) => (
cluster = deposit.children?.find((cluster: TreeNodeData) => cluster.key === url)
cluster = deposit.children?.find((cluster: TreeDataNode) => cluster.key === url)
))
if (deposit && cluster)
return `${deposit.title} / ${cluster.title}`
@ -54,8 +45,8 @@ const getLabel = (wellsTree: TreeNodeData[], value?: string): string | undefined
case 'well':
deposit = wellsTree.find((deposit) => (
cluster = deposit.children?.find((cluster: TreeNodeData) => (
well = cluster.children?.find((well: TreeNodeData) => well.key === url)
cluster = deposit.children?.find((cluster: TreeDataNode) => (
well = cluster.children?.find((well: TreeDataNode) => well.key === url)
))
))
if (deposit && cluster && well)
@ -79,8 +70,26 @@ const sortWellsByActive = (a: WellDto, b: WellDto): number => {
return (a.caption || '')?.localeCompare(b.caption || '')
}
export const WellTreeSelector = memo(({ show, ...other }: TreeProps<TreeNodeData> & { show?: boolean }) => {
const [wellsTree, setWellsTree] = useState<TreeNodeData[]>([])
export type WellTreeSelectorProps = TreeProps<TreeDataNode> & {
show?: boolean
expand?: boolean | Key[]
current?: Key
}
const getExpandKeys = (treeData: TreeDataNode[], depositKeys?: Key[] | boolean): Key[] => {
const out: Key[] = []
treeData.forEach((deposit) => {
if (Array.isArray(depositKeys) && !depositKeys.includes(deposit.key)) return
if (deposit.key) out.push(deposit.key)
deposit.children?.forEach((cluster) => {
if (cluster.key) out.push(cluster.key)
})
})
return out
}
export const WellTreeSelector = memo<WellTreeSelectorProps>(({ show, expand, current, ...other }) => {
const [wellsTree, setWellsTree] = useState<TreeDataNode[]>([])
const [showLoader, setShowLoader] = useState<boolean>(false)
const [visible, setVisible] = useState<boolean>(false)
const [expanded, setExpanded] = useState<Key[]>([])
@ -91,26 +100,20 @@ export const WellTreeSelector = memo(({ show, ...other }: TreeProps<TreeNodeData
const location = useLocation()
useEffect(() => {
setVisible((prev) => show ?? prev)
setExpanded((prev) => {
if (typeof show === 'undefined') return prev
if (!show) return []
const out: Key[] = []
wellsTree.forEach((deposit) => {
if (deposit.key) out.push(deposit.key)
deposit.children?.forEach((cluster) => {
if (cluster.key) out.push(cluster.key)
})
})
return out
})
}, [wellsTree, show])
if (current) setSelected([current])
}, [current])
useEffect(() => setVisible((prev) => show ?? prev), [show])
useEffect(() => {
setExpanded((prev) => expand ? getExpandKeys(wellsTree, expand) : prev)
}, [wellsTree, expand])
useEffect(() => {
invokeWebApiWrapperAsync(
async () => {
const deposits: Array<DepositDto> = await DepositService.getDeposits()
const wellsTree: TreeNodeData[] = deposits.map(deposit =>({
const wellsTree: TreeDataNode[] = deposits.map(deposit =>({
title: deposit.caption,
key: `/deposit/${deposit.id}`,
value: `/deposit/${deposit.id}`,

View File

@ -1,5 +1,5 @@
import { Map, Overlay } from 'pigeon-maps'
import { useState, useEffect, memo } from 'react'
import { useState, useEffect, memo, useMemo } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { Popover, Badge } from 'antd'
@ -49,6 +49,16 @@ const Deposit = memo(() => {
const location = useLocation()
const selectorProps = useMemo(() => {
const hasId = location.pathname.length > '/deposit/'.length
return {
show: true,
expand: hasId ? [location.pathname] : true,
current: hasId ? location.pathname : undefined,
}
}, [location.pathname])
useEffect(() => {
invokeWebApiWrapperAsync(
async () => {
@ -63,7 +73,7 @@ const Deposit = memo(() => {
}, [])
return (
<LayoutPortal noSheet showSelector title={'Месторождение'}>
<LayoutPortal noSheet selector={selectorProps} title={'Месторождение'}>
<LoaderPortal show={showLoader}>
<div className={'h-100vh'}>
<Map {...viewParams}>