import { TreeSelect } from 'antd' import { LabelInValueType } from 'rc-select/lib/Select' import { RawValueType } from 'rc-tree-select/lib/TreeSelect' import { DefaultValueType } from 'rc-tree-select/lib/interface' import { useState, useEffect, ReactNode, useCallback, memo } from 'react' import { useNavigate, useLocation } from 'react-router-dom' 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 => { const result = value?.match(/^\/([^\/]+)\/([^\/?]+)/) // pattern "/:type/:id" if (wellsTree.length <= 0 || !result) return const [url, type] = result let deposit: TreeNodeData | undefined let cluster: TreeNodeData | undefined let well: TreeNodeData | undefined switch (type) { case 'deposit': deposit = wellsTree.find((deposit) => deposit.key === url) if (deposit) return `${deposit.title}` return 'Ошибка! Месторождение не найдено!' case 'cluster': deposit = wellsTree.find((deposit) => ( cluster = deposit.children?.find((cluster: TreeNodeData) => cluster.key === url) )) if (deposit && cluster) return `${deposit.title} / ${cluster.title}` return 'Ошибка! Куст не найден!' case 'well': deposit = wellsTree.find((deposit) => ( cluster = deposit.children?.find((cluster: TreeNodeData) => ( well = cluster.children?.find((well: TreeNodeData) => well.key === url) )) )) if (deposit && cluster && well) return `${deposit.title} / ${cluster.title} / ${well.title}` return 'Ошибка! Скважина не найдена!' default: break } } export const WellTreeSelector = memo(({ ...other }) => { const [wellsTree, setWellsTree] = useState([]) const [showLoader, setShowLoader] = useState(false) const [value, setValue] = useState() const navigate = useNavigate() const location = useLocation() 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, location.pathname)), [wellsTree, location]) const onChange = useCallback((value?: string): void => setValue(getLabel(wellsTree, value)), [wellsTree]) const onSelect = useCallback((value: RawValueType | LabelInValueType): void => { if (['number', 'string'].includes(typeof value)) navigate(String(value), { state: { from: location.pathname }}) }, [navigate, location]) return ( ) }) export default WellTreeSelector