import { TreeSelect } from 'antd' import { DefaultValueType } from 'rc-tree-select/lib/interface' import { useState, useEffect, ReactNode, useCallback, memo } from 'react' import { useHistory, useLocation, useRouteMatch } from 'react-router-dom' import { RawValueType } from 'rc-tree-select/lib/TreeSelect' import { LabelInValueType } from 'rc-select/lib/Select' import { isRawDate } from '@utils' import LoaderPortal from '@components/LoaderPortal' import { WellIcon, WellIconState } from '@components/icons' import { invokeWebApiWrapperAsync } from '@components/factory' import { DepositService, DepositDto } from '@api' import { ReactComponent as DepositIcon } from '@images/DepositIcon.svg' import { ReactComponent as ClusterIcon } from '@images/ClusterIcon.svg' import '@styles/wellTreeSelect.css' export const getWellState = (idState?: number): WellIconState => idState === 1 ? 'active' : 'unknown' 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 getLabel = (wellsTree: TreeNodeData[], value?: string): string | undefined => { if (!value) return value const type = value.replaceAll('/', ' ').trim().split(' ')[0] let deposit: TreeNodeData | undefined let cluster: TreeNodeData | undefined let well: TreeNodeData | undefined switch (type) { case 'cluster': deposit = wellsTree.find((deposit) => ( cluster = deposit.children?.find((cluster: TreeNodeData) => cluster.key === value) )) if (deposit && cluster) return `${deposit.title} / ${cluster.title}` break case 'well': deposit = wellsTree.find((deposit) => ( cluster = deposit.children?.find((cluster: TreeNodeData) => ( well = cluster.children?.find((well: TreeNodeData) => well.key === value) )) )) if (deposit && cluster && well) return `${deposit.title} / ${cluster.title} / ${well.title}` break default: break } return 'Ошибка! Скважина не найдена!' } export const WellTreeSelector = memo(({ ...other }) => { const [wellsTree, setWellsTree] = useState([]) const [showLoader, setShowLoader] = useState(false) const [value, setValue] = useState() const history = useHistory() const location = useLocation() const routeMatch = useRouteMatch('/:route/:id') useEffect(() => { invokeWebApiWrapperAsync( async () => { const deposits: Array = await DepositService.getDeposits() const wellsTree: TreeNodeData[] = deposits.map(deposit =>({ title: deposit.caption, key: `/deposit/${deposit.id}`, value: `/deposit/${deposit.id}`, icon: , children: deposit.clusters?.map(cluster => ({ title: cluster.caption, key: `/cluster/${cluster.id}`, value: `/cluster/${cluster.id}`, icon: , children: cluster.wells?.map(well => ({ title: well.caption, key: `/well/${well.id}`, value: `/well/${well.id}`, icon: })), })), })) setWellsTree(wellsTree) }, setShowLoader, `Не удалось загрузить список скважин`, 'Получить список скважин' ) }, []) useEffect(() => setValue(getLabel(wellsTree, routeMatch?.url)), [wellsTree, routeMatch]) const onChange = useCallback((value?: string): void => setValue(getLabel(wellsTree, value)), [wellsTree]) const onSelect = useCallback((value: RawValueType | LabelInValueType): void => { if (['number', 'string'].includes(typeof value)) history.push({ pathname: String(value), state: { from: location.pathname }}) }, [history, location]) return ( ) }) export default WellTreeSelector