diff --git a/concept/Smbo/EquipmentDetails.jsx b/concept/Smbo/EquipmentDetails.jsx
index 5178236..24b18a7 100755
--- a/concept/Smbo/EquipmentDetails.jsx
+++ b/concept/Smbo/EquipmentDetails.jsx
@@ -1,8 +1,10 @@
import {Row, Col} from 'antd'
-import Documents from '../Documents/DocumentsTemplate'
-import '../../styles/equipment_details.css'
-export default function EquipmentDetails({id, equipmentTimers, equipmentSensors}) {
+import Documents from '../Documents/DocumentsTemplate'
+
+import '@styles/equipment_details.css'
+
+export default function EquipmentDetails({ id, equipmentTimers, equipmentSensors }) {
let stateOfEquipmentDetails = equipmentTimers.map(timer => {
return(
{timer.label}: {timer.value} {timer.unit}
diff --git a/src/components/Private/PrivateMenu.tsx b/src/components/Private/PrivateMenu.tsx
index 1a06311..6894518 100644
--- a/src/components/Private/PrivateMenu.tsx
+++ b/src/components/Private/PrivateMenu.tsx
@@ -1,9 +1,10 @@
import { join } from 'path'
import { Menu, MenuItemProps, MenuProps } from 'antd'
-import { Children, cloneElement, memo, ReactElement } from 'react'
+import { Children, cloneElement, memo, ReactElement, useContext, useMemo } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { isURLAvailable } from '@utils/permissions'
+import { RootPathContext } from '@pages/Main'
export type PrivateMenuProps = MenuProps & { root?: string }
@@ -23,19 +24,22 @@ export const PrivateMenuLink = memo(({ tabName = '', path
)
})
-const PrivateMenuMain = memo(({ root = '', children, ...other }) => {
- const items = Children.toArray(children).map((child) => {
+const PrivateMenuMain = memo(({ root, children, ...other }) => {
+ const rootContext = useContext(RootPathContext)
+ const rootPath = useMemo(() => root ?? rootContext ?? '', [root, rootContext])
+
+ const items = useMemo(() => Children.toArray(children).map((child) => {
const element = child as ReactElement
let key = element.key?.toString()
const visible: boolean | undefined = element.props.visible
if (key && visible !== false) {
key = key.slice(key.lastIndexOf('$') + 1) // Ключ автоматический преобразуется в "(.+)\$ключ"
- const path = join(root, key)
+ const path = join(rootPath, key)
if (visible || isURLAvailable(path))
return cloneElement(element, { key, path, tabName: key })
}
return null
- })
+ }), [children, rootPath])
return
})
diff --git a/src/components/Private/PrivateSwitch.tsx b/src/components/Private/PrivateSwitch.tsx
new file mode 100644
index 0000000..57911ed
--- /dev/null
+++ b/src/components/Private/PrivateSwitch.tsx
@@ -0,0 +1,75 @@
+import { join } from 'path'
+import { Location } from 'history'
+import { Children, cloneElement, memo, ReactElement, ReactNode, useCallback, useContext, useMemo } from 'react'
+
+import { Redirect, Route, Switch, SwitchProps, useLocation } from 'react-router-dom'
+import { isURLAvailable } from '@utils/permissions'
+import { getUserId } from '@utils/storage'
+
+import { RootPathContext } from '@pages/Main'
+
+export type PrivateSwitchProps = SwitchProps & {
+ root?: string
+ redirect?: (location?: Location) => ReactNode
+ elseRedirect?: string | string[]
+}
+
+const getDefaultRedirectPath = () => getUserId() ? '/access_denied' : '/login'
+
+export const defaultRedirect = (location?: Location) => (
+
+)
+
+export const PrivateSwitch = memo(({ root, elseRedirect, redirect = defaultRedirect, children }) => {
+ const rootContext = useContext(RootPathContext)
+ const rootPath = useMemo(() => root ?? rootContext ?? '', [root, rootContext])
+
+ const location = useLocation()
+
+ const toAbsolute = useCallback((path: string) => path.startsWith('/') ? path : join(rootPath, path), [rootPath])
+
+ const items = useMemo(() => Children.toArray(children).map((child) => {
+ const element = child as ReactElement
+ let key = element.key?.toString()
+ if (!key) return null
+ key = key.slice(key.lastIndexOf('$') + 1).replaceAll('=2', ':')
+ // Ключ автоматический преобразуется в "(.+)\$ключ"
+ // Все ":" в ключе заменяются на "=2"
+ // TODO: улучшить метод нормализации ключа
+ const path = toAbsolute(key)
+ return (
+ isURLAvailable(path) ? cloneElement(element) : redirect(location)}
+ />
+ )
+ }), [children, redirect, toAbsolute])
+
+ const defaultRoute = useMemo(() => {
+ if (!elseRedirect) {
+ const path = items.map((elm) => elm?.props.path).find((path) => path && isURLAvailable(path))
+ if (path) return path
+ } else if (Array.isArray(elseRedirect)) {
+ const path = elseRedirect.find((path) => {
+ if (!path) return false
+ return isURLAvailable(toAbsolute(path))
+ })
+ if (path) return toAbsolute(path)
+ } else if(elseRedirect && isURLAvailable(toAbsolute(elseRedirect))) {
+ return toAbsolute(elseRedirect)
+ }
+ return getDefaultRedirectPath()
+ }, [items, elseRedirect, toAbsolute])
+
+ return (
+
+ {items}
+
+
+
+
+ )
+})
+
+export default PrivateSwitch
diff --git a/src/components/Private/index.ts b/src/components/Private/index.ts
index 61de54c..b9cd980 100755
--- a/src/components/Private/index.ts
+++ b/src/components/Private/index.ts
@@ -3,9 +3,11 @@ export { PrivateContent } from './PrivateContent' // TODO: Remove
export { PrivateMenuItem, PrivateMenuItemLink } from './PrivateMenuItem' // TODO: Remove
export { PrivateDefaultRoute } from './PrivateDefaultRoute'
export { PrivateMenu, PrivateMenuLink } from './PrivateMenu'
+export { PrivateSwitch } from './PrivateSwitch'
export type { PrivateRouteProps } from './PrivateRoute'
export type { PrivateContentProps } from './PrivateContent' // TODO: Remove
export type { PrivateMenuItemProps, PrivateMenuItemLinkProps } from './PrivateMenuItem' // TODO: Remove
export type { PrivateDefaultRouteProps } from './PrivateDefaultRoute'
export type { PrivateMenuProps, PrivateMenuLinkProps } from './PrivateMenu'
+export type { PrivateSwitchProps } from './PrivateSwitch'
diff --git a/src/pages/AdminPanel/Telemetry/index.jsx b/src/pages/AdminPanel/Telemetry/index.jsx
index 7ad8b46..9a145e0 100755
--- a/src/pages/AdminPanel/Telemetry/index.jsx
+++ b/src/pages/AdminPanel/Telemetry/index.jsx
@@ -1,41 +1,41 @@
import { Layout } from 'antd'
-import { lazy, memo, Suspense } from 'react'
-import { Switch, useParams } from 'react-router-dom'
+import { lazy, memo, Suspense, useContext, useMemo } from 'react'
+import { useParams } from 'react-router-dom'
-import { PrivateRoute, PrivateDefaultRoute, PrivateMenu } from '@components/Private'
+import { PrivateMenu, PrivateSwitch } from '@components/Private'
import { SuspenseFallback } from '@pages/SuspenseFallback'
+import { RootPathContext } from '@pages/Main'
const TelemetryViewer = lazy(() => import('./TelemetryViewer'))
const TelemetryMerger = lazy(() => import('./TelemetryMerger'))
-const rootPath = '/admin/telemetry'
-
export const Telemetry = memo(() => {
const { tab } = useParams()
- return (
-
-
-
-
-
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/telemetry`, [root])
+ return (
+
-
- }>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ }>
+
+
+
+
+
+
+
-
+
)
})
diff --git a/src/pages/AdminPanel/UserController/index.jsx b/src/pages/AdminPanel/UserController/index.jsx
index 2152cd4..c090d73 100755
--- a/src/pages/AdminPanel/UserController/index.jsx
+++ b/src/pages/AdminPanel/UserController/index.jsx
@@ -188,7 +188,7 @@ export const UserController = memo(() => {
allowClear
placeholder={'Введите текст для поиска (по всем полям за исключением ролей)...'}
onChange={onSearchTextChange}
- style={{ marginBottom: '15px' }}
+ style={{ margin: '15px 0' }}
loading={isSearching}
/>
import( './ClusterController'))
@@ -17,57 +18,48 @@ const PermissionController = lazy(() => import( './PermissionController'))
const TelemetrySection = lazy(() => import( './Telemetry'))
const VisitLog = lazy(() => import( './VisitLog'))
-const rootPath = '/admin'
-
export const AdminPanel = memo(() => {
const { tab } = useParams()
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/admin`, [root])
+ return (
+
-
- }>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
)
})
diff --git a/src/pages/Analytics/Statistics.jsx b/src/pages/Analytics/Statistics.jsx
index c0ad71d..fabd3c1 100755
--- a/src/pages/Analytics/Statistics.jsx
+++ b/src/pages/Analytics/Statistics.jsx
@@ -1,5 +1,5 @@
import { Table as RawTable, Typography } from 'antd'
-import { Fragment, memo, useCallback, useEffect, useState } from 'react'
+import { Fragment, memo, useCallback, useContext, useEffect, useState } from 'react'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
@@ -8,6 +8,8 @@ import { makeGroupColumn, makeNumericColumn, makeNumericRender, makeTextColumn,
import { OperationStatService, WellOperationService } from '@api'
import { arrayOrDefault } from '@utils'
+import { IdWellContext } from '../Well'
+
import '@styles/index.css'
import '@styles/statistics.less'
@@ -62,7 +64,7 @@ const getWellData = async (wellsList) => {
return wellData
}
-export const Statistics = memo(({ idWell }) => {
+export const Statistics = memo(() => {
const [sectionTypes, setSectionTypes] = useState([])
const [avgColumns, setAvgColumns] = useState(defaultColumns)
const [cmpColumns, setCmpColumns] = useState(defaultColumns)
@@ -75,6 +77,8 @@ export const Statistics = memo(({ idWell }) => {
const [cmpData, setCmpData] = useState([])
const [avgRow, setAvgRow] = useState({})
+ const idWell = useContext(IdWellContext)
+
const cmpSpeedRender = useCallback((key) => (section) => {
let spanClass = ''
// Дополнительная проверка на "null" необходима, чтобы значение "0" не стало исключением
diff --git a/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx b/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx
index 6998087..c353e4d 100755
--- a/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx
+++ b/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx
@@ -1,4 +1,4 @@
-import { memo, useCallback, useEffect, useState } from 'react'
+import { memo, useCallback, useContext, useEffect, useState } from 'react'
import { Button, Modal, Popconfirm } from 'antd'
import { Table } from '@components/Table'
@@ -6,14 +6,17 @@ import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { DrillParamsService } from '@api'
+import { IdWellContext } from '@pages/Well'
import { getColumns } from '@pages/WellOperations/WellDrillParams'
-export const NewParamsTable = memo(({ idWell, selectedWellsKeys }) => {
+export const NewParamsTable = memo(({ selectedWellsKeys }) => {
const [params, setParams] = useState([])
const [paramsColumns, setParamsColumns] = useState([])
const [showParamsLoader, setShowParamsLoader] = useState(false)
const [isParamsModalVisible, setIsParamsModalVisible] = useState(false)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => setParamsColumns(await getColumns(idWell))
), [idWell])
diff --git a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx
index 7e1505a..38aa452 100755
--- a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx
+++ b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx
@@ -1,5 +1,5 @@
import { Link, useLocation } from 'react-router-dom'
-import { useState, useEffect, memo, useMemo } from 'react'
+import { useState, useEffect, memo, useMemo, useContext } from 'react'
import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons'
import { Table, Tag, Button, Badge, Divider, Modal, Row, Col } from 'antd'
@@ -15,6 +15,7 @@ import {
getOperations
} from '@utils/functions'
+import { IdWellContext } from '@pages/Well'
import { Tvd } from '@pages/WellOperations/Tvd'
import WellOperationsTable from '@pages/Cluster/WellOperationsTable'
import NewParamsTable from './NewParamsTable'
@@ -29,7 +30,7 @@ const sortBySectionId = (a, b) => a.sectionId - b.sectionId
const filtersSectionsType = []
const DAY_IN_MS = 1000 * 60 * 60 * 24
-export const WellCompositeSections = memo(({ idWell, statsWells, selectedSections }) => {
+export const WellCompositeSections = memo(({ statsWells, selectedSections }) => {
const [selectedWells, setSelectedWells] = useState([])
const [wellOperations, setWellOperations] = useState([])
const [selectedWellsKeys, setSelectedWellsKeys] = useState([])
@@ -38,6 +39,8 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection
const [isTVDModalVisible, setIsTVDModalVisible] = useState(false)
const [isOpsModalVisible, setIsOpsModalVisible] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const location = useLocation()
const rows = useMemo(() => {
@@ -208,9 +211,7 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection
pagination={false}
/>
-
-
-
+
{
+export const WellCompositeEditor = memo(({ rootPath }) => {
const { tab } = useParams()
+ const idWell = useContext(IdWellContext)
const [statsWells, setStatsWells] = useState([])
const [showLoader, setShowLoader] = useState(false)
@@ -68,27 +67,18 @@ export const WellCompositeEditor = memo(({ idWell, rootPath }) => {
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/pages/Analytics/index.jsx b/src/pages/Analytics/index.jsx
index bbe5243..1a38c6a 100755
--- a/src/pages/Analytics/index.jsx
+++ b/src/pages/Analytics/index.jsx
@@ -1,36 +1,35 @@
-import { memo, useMemo } from 'react'
+import { memo, useContext, useMemo } from 'react'
+import { useParams } from 'react-router-dom'
import { Layout } from 'antd'
-import { Switch, useParams } from 'react-router-dom'
-import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private'
+import { PrivateMenu, PrivateSwitch } from '@components/Private'
-import WellCompositeEditor from './WellCompositeEditor'
import Statistics from './Statistics'
+import WellCompositeEditor from './WellCompositeEditor'
+import { RootPathContext } from '@pages/Main'
-export const Analytics = memo(({ idWell }) => {
+export const Analytics = memo(() => {
const { tab } = useParams()
- const rootPath = useMemo(() => `/well/${idWell}/analytics`, [idWell])
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/analytics`, [root])
return (
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
)
})
diff --git a/src/pages/Documents/DocumentsTemplate.jsx b/src/pages/Documents/DocumentsTemplate.jsx
index f786551..dc98a2e 100755
--- a/src/pages/Documents/DocumentsTemplate.jsx
+++ b/src/pages/Documents/DocumentsTemplate.jsx
@@ -1,4 +1,4 @@
-import { useState, useEffect, useMemo, useCallback } from 'react'
+import { useState, useEffect, useMemo, useCallback, useContext } from 'react'
import { DatePicker, Button, Input } from 'antd'
import { FileService } from '@api'
@@ -9,6 +9,8 @@ import { EditableTable, makeColumn, makeDateColumn, makeNumericColumn, makePagin
import { invokeWebApiWrapperAsync, downloadFile, formatBytes } from '@components/factory'
import { hasPermission } from '@utils/permissions'
+import { IdWellContext } from '@pages/Well'
+
const pageSize = 12
const { RangePicker } = DatePicker
const { Search } = Input
@@ -30,7 +32,7 @@ const columns = [
makeColumn('Компания', 'company', { render: (_, record) => })
]
-export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, customColumns, beforeTable, onChange, tableName }) => {
+export const DocumentsTemplate = ({ idCategory, idWell: wellId, accept, headerChild, customColumns, beforeTable, onChange, tableName }) => {
const [page, setPage] = useState(1)
const [filterDataRange, setFilterDataRange] = useState([])
const [filterCompanyName, setFilterCompanyName] = useState([])
@@ -39,6 +41,9 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus
const [files, setFiles] = useState([])
const [showLoader, setShowLoader] = useState(false)
+ const idwellContext = useContext(IdWellContext)
+ const idWell = useMemo(() => wellId ?? idwellContext, [wellId])
+
const uploadUrl = useMemo(() => `/api/well/${idWell}/files/?idCategory=${idCategory}`, [idWell, idCategory])
const mergedColumns = useMemo(() => [...columns, ...(customColumns ?? [])], [customColumns])
diff --git a/src/pages/Documents/index.jsx b/src/pages/Documents/index.jsx
index e429b20..3c79213 100755
--- a/src/pages/Documents/index.jsx
+++ b/src/pages/Documents/index.jsx
@@ -1,12 +1,12 @@
-import { join } from 'path'
-import { memo, useMemo } from 'react'
-import { Layout } from 'antd'
+import { useParams } from 'react-router-dom'
+import { memo, useContext, useMemo } from 'react'
import { FolderOutlined } from '@ant-design/icons'
-import { Switch, useParams } from 'react-router-dom'
+import { Layout } from 'antd'
-import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private'
+import { PrivateMenu, PrivateSwitch } from '@components/Private'
import DocumentsTemplate from './DocumentsTemplate'
+import { RootPathContext } from '@pages/Main'
const { Content } = Layout
@@ -23,13 +23,14 @@ export const documentCategories = [
{ id: 9, key: 'closingService', title: 'Сервис по заканчиванию скважины' },
]
-export const MenuDocuments = memo(({ idWell }) => {
+export const MenuDocuments = memo(() => {
const { category } = useParams()
- const root = useMemo(() => `/well/${idWell}/document`, [idWell])
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/document`, [root])
return (
- <>
-
+
+
{documentCategories.map(category => (
{
-
+ cat.key)}>
{documentCategories.map(category => (
-
-
-
+
))}
- join(root, cat.key))}/>
-
+
- >
+
)
})
diff --git a/src/pages/DrillingProgram/CategoryAdder.jsx b/src/pages/DrillingProgram/CategoryAdder.jsx
index dd45dad..66534e7 100755
--- a/src/pages/DrillingProgram/CategoryAdder.jsx
+++ b/src/pages/DrillingProgram/CategoryAdder.jsx
@@ -1,11 +1,13 @@
import { Form, Select } from 'antd'
import { FileAddOutlined } from '@ant-design/icons'
-import { memo, useCallback, useEffect, useState } from 'react'
+import { memo, useCallback, useContext, useEffect, useState } from 'react'
import Poprompt from '@components/selectors/Poprompt'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { DrillingProgramService } from '@api'
+import { IdWellContext } from '@pages/Well'
+
import '@styles/drilling_program.less'
const catSelectorRules = [{
@@ -13,12 +15,14 @@ const catSelectorRules = [{
message: 'Пожалуйста, выберите категории'
}]
-export const CategoryAdder = memo(({ categories, idWell, onUpdate, className, ...other }) => {
+export const CategoryAdder = memo(({ categories, onUpdate, className, ...other }) => {
const [options, setOptions] = useState([])
const [value, setValue] = useState([])
const [showLoader, setShowLoader] = useState(false)
const [showCatLoader, setShowCatLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
setOptions(categories.map((category) => ({
diff --git a/src/pages/DrillingProgram/CategoryEditor.jsx b/src/pages/DrillingProgram/CategoryEditor.jsx
index 5a01b67..4bedc5e 100755
--- a/src/pages/DrillingProgram/CategoryEditor.jsx
+++ b/src/pages/DrillingProgram/CategoryEditor.jsx
@@ -1,5 +1,5 @@
import { Input, Modal, Radio } from 'antd'
-import { memo, useCallback, useEffect, useMemo, useState } from 'react'
+import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { BehaviorSubject, debounceTime, distinctUntilChanged, filter, map } from 'rxjs'
import { UserView } from '@components/views'
@@ -9,6 +9,8 @@ import { makeColumn, makeNumericSorter, Table } from '@components/Table'
import { DrillingProgramService } from '@api'
import { arrayOrDefault } from '@utils'
+import { IdWellContext } from '@pages/Well'
+
const userRules = [
{ label: 'Нет', value: 0 },
{ label: 'Публикатор', value: 1 },
@@ -17,7 +19,7 @@ const userRules = [
const SEARCH_TIMEOUT = 400
-export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => {
+export const CategoryEditor = memo(({ visible, category, onClosed }) => {
const [title, setTitle] = useState()
const [users, setUsers] = useState([])
const [allUsers, setAllUsers] = useState([])
@@ -27,6 +29,8 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) =>
const [searchValue, setSearchValue] = useState('')
const [subject, setSubject] = useState(null)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const filteredUsers = users.filter(({ user }) => user && [
diff --git a/src/pages/DrillingProgram/CategoryHistory.jsx b/src/pages/DrillingProgram/CategoryHistory.jsx
index 1df55ad..b9f1424 100755
--- a/src/pages/DrillingProgram/CategoryHistory.jsx
+++ b/src/pages/DrillingProgram/CategoryHistory.jsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useState } from 'react'
+import { useCallback, useContext, useEffect, useState } from 'react'
import { Button, DatePicker, Input, Modal } from 'antd'
import { CompanyView } from '@components/views'
@@ -10,6 +10,7 @@ import { arrayOrDefault, formatDate } from '@utils'
import { FileService } from '@api'
import MarksCard from './MarksCard'
+import { IdWellContext } from '@pages/Well'
import '@styles/drilling_program.less'
@@ -54,7 +55,7 @@ export const historyColumns = [
})
]
-export const CategoryHistory = ({ idWell, idCategory, visible, onClose }) => {
+export const CategoryHistory = ({ idCategory, visible, onClose }) => {
const [data, setData] = useState([])
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
@@ -64,6 +65,8 @@ export const CategoryHistory = ({ idWell, idCategory, visible, onClose }) => {
const [isLoading, setIsLoading] = useState(false)
const [companyName, setCompanyName] = useState('')
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
if (!visible) return
diff --git a/src/pages/DrillingProgram/CategoryRender.jsx b/src/pages/DrillingProgram/CategoryRender.jsx
index d3a168e..92f6e27 100755
--- a/src/pages/DrillingProgram/CategoryRender.jsx
+++ b/src/pages/DrillingProgram/CategoryRender.jsx
@@ -1,4 +1,4 @@
-import { memo, useCallback, useMemo, useState } from 'react'
+import { memo, useCallback, useContext, useMemo, useState } from 'react'
import { Button, Input, Popconfirm, Form } from 'antd'
import {
DeleteOutlined,
@@ -16,6 +16,7 @@ import { DrillingProgramService } from '@api'
import { formatDate } from '@utils'
import MarksCard from './MarksCard'
+import { IdWellContext } from '@pages/Well'
import '@styles/drilling_program.less'
@@ -34,7 +35,7 @@ const CommentPrompt = memo(({ isRequired = true, ...props }) => (
))
-export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHistory, setIsLoading, ...other }) => {
+export const CategoryRender = memo(({ partData, onUpdate, onEdit, onHistory, setIsLoading, ...other }) => {
const {
idFileCategory,
name: title, // Название категории
@@ -44,6 +45,8 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist
file // Информация о файле
} = partData ?? {}
+ const idWell = useContext(IdWellContext)
+
const uploadUrl = useMemo(() => `/api/well/${idWell}/drillingProgram/part/${idFileCategory}`, [idWell, idFileCategory])
const approvedMarks = useMemo(() => file?.fileMarks?.filter((mark) => mark.idMarkType === 1), [file])
const rejectMarks = useMemo(() => file?.fileMarks?.filter((mark) => mark.idMarkType === 0), [file])
diff --git a/src/pages/DrillingProgram/index.jsx b/src/pages/DrillingProgram/index.jsx
index 303d240..1b08c73 100755
--- a/src/pages/DrillingProgram/index.jsx
+++ b/src/pages/DrillingProgram/index.jsx
@@ -8,7 +8,7 @@ import {
ReloadOutlined,
WarningOutlined,
} from '@ant-design/icons'
-import { memo, useCallback, useEffect, useMemo, useState } from 'react'
+import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import LoaderPortal from '@components/LoaderPortal'
import { downloadFile, formatBytes, invokeWebApiWrapperAsync } from '@components/factory'
@@ -19,6 +19,7 @@ import CategoryAdder from './CategoryAdder'
import CategoryRender from './CategoryRender'
import CategoryEditor from './CategoryEditor'
import CategoryHistory from './CategoryHistory'
+import { IdWellContext } from '@pages/Well'
import '@styles/drilling_program.less'
@@ -38,7 +39,7 @@ const stateString = {
[idStateUnknown]: { icon: WarningOutlined, text: 'Неизвестно' },
}
-export const DrillingProgram = memo(({ idWell }) => {
+export const DrillingProgram = memo(() => {
const [selectedCategory, setSelectedCategory] = useState()
const [historyVisible, setHistoryVisible] = useState(false)
const [editorVisible, setEditorVisible] = useState(false)
@@ -46,6 +47,8 @@ export const DrillingProgram = memo(({ idWell }) => {
const [categories, setCategories] = useState([])
const [data, setData] = useState({})
+ const idWell = useContext(IdWellContext)
+
const {
idState,
permissionToEdit,
@@ -99,11 +102,7 @@ export const DrillingProgram = memo(({ idWell }) => {
Программа бурения
{permissionToEdit && (
-
+
)}
@@ -143,7 +142,6 @@ export const DrillingProgram = memo(({ idWell }) => {
{parts?.map?.((part, idx) => part && (
{
{permissionToEdit && (
<>
part.idFileCategory === selectedCategory) ?? {}}
@@ -163,7 +160,6 @@ export const DrillingProgram = memo(({ idWell }) => {
)}
setHistoryVisible(false)}
visible={historyVisible}
diff --git a/src/pages/Main.jsx b/src/pages/Main.jsx
index e090edf..183da19 100755
--- a/src/pages/Main.jsx
+++ b/src/pages/Main.jsx
@@ -1,4 +1,4 @@
-import { memo } from 'react'
+import { createContext, memo } from 'react'
import { Route, Switch } from 'react-router-dom'
import { AdminLayoutPortal, LayoutPortal } from '@components/Layout'
@@ -10,33 +10,37 @@ import Deposit from './Deposit'
import AdminPanel from './AdminPanel'
import AccessDenied from './AccessDenied'
+export const RootPathContext = createContext('')
+
export const Main = memo(() => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
))
export default Main
diff --git a/src/pages/Measure/MeasureTable.jsx b/src/pages/Measure/MeasureTable.jsx
index 25e7fd5..32bd830 100755
--- a/src/pages/Measure/MeasureTable.jsx
+++ b/src/pages/Measure/MeasureTable.jsx
@@ -1,4 +1,4 @@
-import { useState, useEffect, memo, useMemo, useCallback } from 'react'
+import { useState, useEffect, memo, useMemo, useCallback, useContext } from 'react'
import { Button, Form, Input, Popconfirm, Timeline } from 'antd'
import {
CheckSquareOutlined,
@@ -16,6 +16,7 @@ import { formatDate } from '@utils'
import { MeasureService } from '@api'
import { View } from './View'
+import { IdWellContext } from '@pages/Well'
import '@styles/index.css'
import '@styles/measure.css'
@@ -25,13 +26,15 @@ const createEditingColumns = (cols, renderDelegate) =>
const disabled = !hasPermission('Measure.edit')
-export const MeasureTable = memo(({ idWell, group, updateMeasuresFunc, additionalButtons }) => {
+export const MeasureTable = memo(({ group, updateMeasuresFunc, additionalButtons }) => {
const [showLoader, setShowLoader] = useState(false)
const [displayedValues, setDisplayedValues] = useState({})
const [editingColumns, setEditingColumns] = useState(group.columns)
const [isTableEditing, setIsTableEditing] = useState(false)
const [editingActionName, setEditingActionName] = useState('')
+ const idWell = useContext(IdWellContext)
+
const [measuresForm] = Form.useForm()
const data = useMemo(() => group?.values?.length > 0 ? group.values : [group?.defaultValue], [group?.defaultValue, group?.values])
diff --git a/src/pages/Measure/index.jsx b/src/pages/Measure/index.jsx
index adf6b4c..af15e53 100755
--- a/src/pages/Measure/index.jsx
+++ b/src/pages/Measure/index.jsx
@@ -1,5 +1,5 @@
import { Button } from 'antd'
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
import { TableOutlined } from '@ant-design/icons'
import { MeasureService } from '@api'
@@ -11,6 +11,7 @@ import { InclinometryTable } from './InclinometryTable'
import { columnsNnb, nnbDefaultData } from './nnbData'
import { columnsMudDiagram, mudDiagramDefaultData } from './mudDiagramData'
import { columnsDrillingFluid, drillingFluidDefaultData } from './drillingFluidData'
+import { IdWellContext } from '@pages/Well'
const defaultData = [
{
@@ -41,12 +42,14 @@ const defaultData = [
}
]
-export const Measure = memo(({ idWell }) => {
+export const Measure = memo(() => {
const [showLoader, setShowLoader] = useState(false)
const [isMeasuresUpdating, setIsMeasuresUpdating] = useState(true)
const [data, setData] = useState(defaultData)
const [tableIdx, setTableIdx] = useState(-1)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
if (!isMeasuresUpdating) return
@@ -73,7 +76,6 @@ export const Measure = memo(({ idWell }) => {
{data.map((group, idx) => (
setIsMeasuresUpdating(true)}
additionalButtons={group.additionalButtons?.(group, idx, setTableIdx)}
diff --git a/src/pages/Report/Reports.jsx b/src/pages/Report/Reports.jsx
index cf44431..c5fb7ca 100755
--- a/src/pages/Report/Reports.jsx
+++ b/src/pages/Report/Reports.jsx
@@ -1,5 +1,5 @@
import { Button, Tooltip } from 'antd'
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
import { FilePdfOutlined, FileTextOutlined } from '@ant-design/icons'
import { ReportService } from '@api'
@@ -7,6 +7,7 @@ import { formatDate, periodToString } from '@utils'
import LoaderPortal from '@components/LoaderPortal'
import { Table, makeDateSorter, makeNumericSorter } from '@components/Table'
import { invokeWebApiWrapperAsync, downloadFile } from '@components/factory'
+import { IdWellContext } from '@pages/Well'
const imgPaths = {
'.pdf': ,
@@ -55,10 +56,12 @@ const columns = [
},
]
-export const Reports = memo(({ idWell }) => {
+export const Reports = memo(() => {
const [reports, setReports] = useState([])
const [showLoader, setShowLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const reportsResponse = await ReportService.getAllReportsNamesByWell(idWell)
diff --git a/src/pages/Report/index.jsx b/src/pages/Report/index.jsx
index 866ecdf..0c1f2e0 100755
--- a/src/pages/Report/index.jsx
+++ b/src/pages/Report/index.jsx
@@ -1,6 +1,6 @@
import 'moment/locale/ru'
import moment from 'moment'
-import { useState, useEffect, memo, useCallback } from 'react'
+import { useState, useEffect, memo, useCallback, useContext } from 'react'
import { Radio, Button, Select, notification } from 'antd'
import { ReportService } from '@api'
@@ -11,6 +11,7 @@ import { DateRangeWrapper } from 'components/Table/DateRangeWrapper'
import { Reports } from './Reports'
import { ReportCreationNotify } from './ReportCreationNotify'
+import { IdWellContext } from '../Well'
const timePeriodNames = [
{ label: '1 секунда', value: 1 },
@@ -32,7 +33,7 @@ const reportFormats = [
{ value: 1, label: 'LAS' },
]
-export const Report = memo(({ idWell }) => {
+export const Report = memo(() => {
const [aviableDateRange, setAviableDateRange] = useState([moment(), moment()])
const [filterDateRange, setFilterDateRange] = useState([
moment().subtract(1, 'days').startOf('day'),
@@ -43,6 +44,8 @@ export const Report = memo(({ idWell }) => {
const [pagesCount, setPagesCount] = useState(0)
const [showLoader, setShowLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const handleReportCreation = useCallback(async () => await invokeWebApiWrapperAsync(
async () => {
const taskId = await ReportService.createReport(
@@ -166,7 +169,7 @@ export const Report = memo(({ idWell }) => {
-
+
)
})
diff --git a/src/pages/Telemetry/Archive/index.jsx b/src/pages/Telemetry/Archive/index.jsx
index 4c37e9f..1a45d4e 100755
--- a/src/pages/Telemetry/Archive/index.jsx
+++ b/src/pages/Telemetry/Archive/index.jsx
@@ -1,5 +1,5 @@
/* eslint-disable react-hooks/exhaustive-deps */
-import { useState, useEffect, memo, useCallback } from 'react'
+import { useState, useEffect, memo, useCallback, useContext } from 'react'
import { Flex } from '@components/Grid'
import LoaderPortal from '@components/LoaderPortal'
@@ -8,6 +8,7 @@ import { DatePickerWrapper, makeDateSorter } from '@components/Table'
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
import { TelemetryDataSaubService } from '@api'
+import { IdWellContext } from '@pages/Well'
import { normalizeData } from '../TelemetryView'
import { ArchiveDisplay, cutData } from './ArchiveDisplay'
@@ -61,7 +62,7 @@ const range = (start, end) => {
return result
}
-export const Archive = memo(({ idWell }) => {
+export const Archive = memo(() => {
const [dataSaub, setDataSaub] = useState([])
const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() })
const [chartInterval, setChartInterval] = useState(parseInt(defaultPeriod) * 1000)
@@ -69,6 +70,8 @@ export const Archive = memo(({ idWell }) => {
const [showLoader, setShowLoader] = useState(false)
const [loaded, setLoaded] = useState(null)
+ const idWell = useContext(IdWellContext)
+
const onGraphWheel = useCallback((e) => {
if (loaded && dateLimit.from && dateLimit.to) {
setStartDate((prevStartDate) => {
diff --git a/src/pages/Telemetry/DashboardNNB/index.jsx b/src/pages/Telemetry/DashboardNNB/index.jsx
index eb5f8b8..cf16bcf 100644
--- a/src/pages/Telemetry/DashboardNNB/index.jsx
+++ b/src/pages/Telemetry/DashboardNNB/index.jsx
@@ -1,4 +1,4 @@
-import { memo, useCallback, useEffect, useMemo, useReducer, useState } from 'react'
+import { memo, useCallback, useContext, useEffect, useMemo, useReducer, useState } from 'react'
import { useHistory, useParams } from 'react-router-dom'
import { CloseOutlined } from '@ant-design/icons'
import { Button, Menu, Popconfirm } from 'antd'
@@ -19,10 +19,12 @@ import {
WitsRecord61Service,
} from '@api'
+import { IdWellContext } from '@pages/Well'
+import { RootPathContext } from '@pages/Main'
+import AddGroupWindow from './AddGroupWindow'
import AddWidgetWindow, { makeWidgetFromWits } from './AddWidgetWindow'
import '@styles/dashboard_nnb.less'
-import AddGroupWindow from './AddGroupWindow'
const getWitsInfo = async () => {
// TODO: Добавить expire с принудительным обновлением
@@ -105,19 +107,21 @@ const groupsReducer = (groups, action) => {
return newGroups
}
-export const DashboardNNB = memo(({ idWell }) => {
+export const DashboardNNB = memo(() => {
const [groups, dispatchGroups] = useReducer(groupsReducer, [])
const [witsInfo, setWitsInfo] = useState([])
const [isLoading, setIsLoading] = useState(false)
const [selectedSettings, setSelectedSettings] = useState(null)
const [values, setValues] = useState({})
- const root = useMemo(() => `/well/${idWell}/telemetry/dashboard_nnb`, [idWell])
+ const idWell = useContext(IdWellContext)
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/dashboard_nnb`, [root])
const history = useHistory()
const { tab: selectedGroup } = useParams()
if (!selectedGroup && groups?.length > 0)
- history.push(`${root}/${groups[0].id}`)
+ history.push(`${rootPath}/${groups[0].id}`)
const group = useMemo(() => ({
@@ -172,8 +176,8 @@ export const DashboardNNB = memo(({ idWell }) => {
const removeGroup = useCallback((id) => {
dispatchGroups({ type: 'remove_group', groupId: `${id}` })
- if (id === selectedGroup) history.push(`${root}`)
- }, [root, history, selectedGroup])
+ if (id === selectedGroup) history.push(`${rootPath}`)
+ }, [rootPath, history, selectedGroup])
const addWidget = useCallback((settings) => dispatchGroups({
type: 'add_widget',
@@ -226,7 +230,7 @@ export const DashboardNNB = memo(({ idWell }) => {
} />
)}
-
+
))}
diff --git a/src/pages/Telemetry/Messages.jsx b/src/pages/Telemetry/Messages.jsx
index 2500ada..e97732b 100755
--- a/src/pages/Telemetry/Messages.jsx
+++ b/src/pages/Telemetry/Messages.jsx
@@ -1,10 +1,12 @@
-import moment from 'moment'
-import { useState, useEffect, memo, useCallback } from 'react'
+import { useState, useEffect, memo, useCallback, useContext } from 'react'
import { Table, Select, DatePicker, Input } from 'antd'
-import { MessageService } from '@api'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
+import { makeColumn, makeDateColumn, makeNumericSorter } from '@components/Table'
+import { MessageService } from '@api'
+
+import { IdWellContext } from '../Well'
import '@styles/message.css'
@@ -22,41 +24,18 @@ const categoryDictionary = {
// Конфигурация таблицы
export const columns = [
- {
+ makeDateColumn('Дата', 'date', undefined, undefined, { width: '10rem' }),
+ makeColumn('Глубина', 'wellDepth', { width: '10rem', render: depth => {depth.toFixed(2)} м. }),
+ makeColumn('Категория', 'categoryId', {
width: '10rem',
- title: 'Дата',
- key: 'date',
- dataIndex: 'date',
- render: item => moment(item).format('DD MMM YYYY, HH:mm:ss'),
- sorter: (a, b) => new Date(b.date) - new Date(a.date),
- sortDirections: ['descend', 'ascend'],
- }, {
- width: '10rem',
- title: 'Глубина',
- key: 'wellDepth',
- dataIndex: 'wellDepth',
- render: depth => {depth.toFixed(2)} м.,
- }, {
- width: '10rem',
- title: 'Категория',
- key: 'categoryId',
- dataIndex: 'categoryId',
render: (_, item) => categoryDictionary[item.categoryId].title,
style: (_, item) => categoryDictionary[item.categoryId]?.style,
- sorter: (a, b) => a.categoryId - b.categoryId,
+ sorter: makeNumericSorter('categoryId'),
sortDirections: ['descend', 'ascend'],
ellipsis: true,
- }, {
- title: 'Сообщение',
- key: 'message',
- dataIndex: 'message',
- onFilter: (value, record) => record.name.indexOf(value) === 0,
- }, {
- width: '10rem',
- title: 'Пользователь',
- key: 'user',
- dataIndex: 'user',
- },
+ }),
+ makeColumn('Сообщение', 'message', { onFilter: (value, record) => record.name.indexOf(value) === 0 }),
+ makeColumn('Пользователь', 'user', { width: '10rem' }),
]
const filterOptions = [
@@ -68,7 +47,7 @@ const filterOptions = [
const children = filterOptions.map((line) => )
// Данные для таблицы
-export const Messages = memo(({ idWell }) => {
+export const Messages = memo(() => {
const [messages, setMessages] = useState([])
const [pagination, setPagination] = useState(null)
const [page, setPage] = useState(1)
@@ -77,6 +56,8 @@ export const Messages = memo(({ idWell }) => {
const [searchString, setSearchString] = useState('')
const [showLoader, setShowLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const onChangeSearchString = useCallback((message) => setSearchString(message.length > 2 ? message : ''), [])
useEffect(() => invokeWebApiWrapperAsync(
diff --git a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx
index b2fd566..f839c02 100755
--- a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx
+++ b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx
@@ -1,5 +1,5 @@
import { Table } from 'antd'
-import { useState, useEffect, useCallback, memo } from 'react'
+import { useState, useEffect, useCallback, memo, useContext } from 'react'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
@@ -7,13 +7,16 @@ import { Subscribe } from '@services/signalr'
import { MessageService } from '@api'
import { columns } from '../Messages'
+import { IdWellContext } from '@pages/Well'
import '@styles/message.css'
-export const ActiveMessagesOnline = memo(({ idWell }) => {
+export const ActiveMessagesOnline = memo(() => {
const [messages, setMessages] = useState([])
const [loader, setLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const handleReceiveMessages = useCallback((messages) => {
if (messages)
setMessages(messages.items.splice(0, 4))
diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx
index 12006ea..985dd96 100755
--- a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx
+++ b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx
@@ -1,4 +1,4 @@
-import { memo, useCallback, useMemo, useState } from 'react'
+import { memo, useCallback, useContext, useMemo, useState } from 'react'
import { Select, Modal, Input, InputNumber } from 'antd'
import { SetpointsService } from '@api'
@@ -8,12 +8,16 @@ import { invokeWebApiWrapperAsync } from '@components/factory'
import { makeNumericRender, EditableTable } from '@components/Table'
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
-export const SetpointSender = memo(({ idWell, onClose, visible, setpointNames }) => {
+import { IdWellContext } from '@pages/Well'
+
+export const SetpointSender = memo(({ onClose, visible, setpointNames }) => {
const [expirePeriod, setExpirePeriod] = useState(defaultPeriod)
const [comment, setComment] = useState('')
const [setpoints, setSetpoints] = useState([])
const [isLoading, setIsLoading] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const addingColumns = useMemo(() => [
{
title: 'Наименование уставки',
diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx
index 2339ea2..bf54c98 100755
--- a/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx
+++ b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx
@@ -1,5 +1,5 @@
import { Button, Modal } from 'antd'
-import { useState, useEffect, memo, useCallback, useMemo } from 'react'
+import { useState, useEffect, memo, useCallback, useMemo, useContext } from 'react'
import { Table } from '@components/Table'
import { UserView } from '@components/views'
@@ -10,10 +10,11 @@ import { makeStringCutter } from '@utils/string'
import { formatDate } from '@utils'
import { SetpointsService } from '@api'
+import { IdWellContext } from '@pages/Well'
import SetpointSender from './SetpointSender'
import { SetpointViewer, getSetpointStatus } from './SetpointViewer'
-export const Setpoints = memo(({ idWell, ...other }) => {
+export const Setpoints = memo(({ ...other }) => {
const [isModalVisible, setIsModalVisible] = useState(false)
const [isSenderVisible, setIsSenderVisible] = useState(false)
const [isViewerVisible, setIsViewerVisible] = useState(false)
@@ -22,6 +23,8 @@ export const Setpoints = memo(({ idWell, ...other }) => {
const [selected, setSelected] = useState(null)
const [setpointNames, setSetpointNames] = useState([])
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const names = await SetpointsService.getSetpointsNamesByIdWell(idWell)
@@ -102,7 +105,6 @@ export const Setpoints = memo(({ idWell, ...other }) => {
{
+import { IdWellContext } from '@pages/Well'
+
+export const WirelineRunOut = memo(() => {
const [twro, setTwro] = useState({})
const [isLoading, setIsLoading] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const update = useCallback(() => invokeWebApiWrapperAsync(
async () => {
const twro = await TelemetryWirelineRunOutService.getData(idWell)
diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx
index c11ae6f..aa0083a 100755
--- a/src/pages/Telemetry/TelemetryView/index.jsx
+++ b/src/pages/Telemetry/TelemetryView/index.jsx
@@ -1,5 +1,5 @@
import { Select } from 'antd'
-import { useState, useEffect, useCallback } from 'react'
+import { useState, useEffect, useCallback, useContext } from 'react'
import {
DrillFlowChartService,
@@ -22,6 +22,8 @@ import ActiveMessagesOnline from './ActiveMessagesOnline'
import { ModeDisplay } from './ModeDisplay'
import { UserOfWell } from './UserOfWells'
import { Setpoints } from './Setpoints'
+import WirelineRunOut from './WirelineRunOut'
+import { IdWellContext } from '@pages/Well'
import MomentStabPicEnabled from '@images/DempherOn.png'
import MomentStabPicDisabled from '@images/DempherOff.png'
@@ -29,7 +31,6 @@ import SpinPicEnabled from '@images/SpinEnabled.png'
import SpinPicDisabled from '@images/SpinDisabled.png'
import '@styles/message.css'
-import WirelineRunOut from './WirelineRunOut'
const { Option } = Select
@@ -303,7 +304,7 @@ export const normalizeData = (data) => data?.map(item => ({
blockSpeed: Math.abs(item.blockSpeed)
})) ?? []
-export default function TelemetryView({ idWell }) {
+export default function TelemetryView() {
const [dataSaub, setDataSaub] = useState([])
const [dataSpin, setDataSpin] = useState([])
const [chartInterval, setChartInterval] = useState(defaultPeriod)
@@ -312,6 +313,8 @@ export default function TelemetryView({ idWell }) {
const [flowChartData, setFlowChartData] = useState([])
const [rop, setRop] = useState(null)
+ const idWell = useContext(IdWellContext)
+
const handleDataSaub = useCallback((data) => {
if (data) {
const dataSaub = normalizeData(data)
@@ -392,9 +395,9 @@ export default function TelemetryView({ idWell }) {
-
+
-
+
MSE
diff --git a/src/pages/Telemetry/index.jsx b/src/pages/Telemetry/index.jsx
index 77026e1..85189ba 100755
--- a/src/pages/Telemetry/index.jsx
+++ b/src/pages/Telemetry/index.jsx
@@ -1,58 +1,47 @@
-import { Switch, useParams } from 'react-router-dom'
-import { memo, useMemo } from 'react'
+import { useParams } from 'react-router-dom'
+import { memo, useContext, useMemo } from 'react'
import { Layout } from 'antd'
import { AlertOutlined, FundViewOutlined, DatabaseOutlined } from '@ant-design/icons'
-import PrivateMenu from '@components/Private/PrivateMenu'
-import { PrivateRoute, PrivateDefaultRoute } from '@components/Private'
+import { PrivateSwitch, PrivateMenu } from '@components/Private'
import Archive from './Archive'
import Messages from './Messages'
import DashboardNNB from './DashboardNNB'
import TelemetryView from './TelemetryView'
+import { RootPathContext } from '@pages/Main'
import '@styles/index.css'
const { Content } = Layout
-export const Telemetry = memo(({ idWell }) => {
+export const Telemetry = memo(() => {
const { tab } = useParams()
- const rootPath = useMemo(() => `/well/${idWell}/telemetry`, [idWell])
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/telemetry`, [root])
return (
-
-
- } title={'Мониторинг'}/>
- } title={'Сообщения'} />
- } title={'Архив'} />
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ } title={'Мониторинг'}/>
+ } title={'Сообщения'} />
+ } title={'Архив'} />
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
)
})
diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx
index 904b966..f679a67 100755
--- a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx
+++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx
@@ -1,15 +1,19 @@
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
import { TelemetryAnalyticsService } from '@api'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { ChartTelemetryDepthToDay } from '@components/charts/ChartTelemetryDepthToDay'
-export const TelemetryAnalysisDepthToDay = memo(({ idWell }) => {
+import { IdWellContext } from '@pages/Well'
+
+export const TelemetryAnalysisDepthToDay = memo(() => {
const [depthData, setDepthData] = useState([])
const [bitPositionData, setBitPositionData] = useState([])
const [loader, setLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const depthToDayData = await TelemetryAnalyticsService.getWellDepthToDay(idWell)
diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx
index 989165f..c5cb90e 100755
--- a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx
+++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx
@@ -1,11 +1,13 @@
import { Select } from 'antd'
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
-import { arrayOrDefault } from '@utils'
-import { TelemetryAnalyticsService } from '@api'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { ChartTelemetryDepthToInterval } from '@components/charts/ChartTelemetryDepthToInterval'
+import { TelemetryAnalyticsService } from '@api'
+import { arrayOrDefault } from '@utils'
+
+import { IdWellContext } from '@pages/Well'
const timePeriodCollection = [
{ value: '3600', label: '1 час' },
@@ -14,11 +16,13 @@ const timePeriodCollection = [
{ value: '86400', label: '24 часа' }
]
-export const TelemetryAnalysisDepthToInterval = memo(({ idWell }) => {
+export const TelemetryAnalysisDepthToInterval = memo(() => {
const [depthToIntervalData, setDepthToIntervalData] = useState([])
const [chartInterval, setChartInterval] = useState(86400)
const [loader, setLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const depthToIntervalData = await TelemetryAnalyticsService.getWellDepthToInterval(idWell, chartInterval)
diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx
index 9337c78..37e35b5 100755
--- a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx
+++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx
@@ -1,20 +1,24 @@
import moment from 'moment'
import { Form, DatePicker } from 'antd'
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
import { TelemetryAnalyticsService } from '@api'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { ChartTelemetryOperationsSummary } from '@components/charts/ChartTelemetryOperationsSummary'
+import { IdWellContext } from '@pages/Well'
+
const { RangePicker } = DatePicker
-export const TelemetryAnalysisOperationsSummary = memo(({ idWell }) => {
+export const TelemetryAnalysisOperationsSummary = memo(() => {
const [avilableDatesRange, setAviableDatesRange] = useState([moment(),moment()])
const [filterDateRange, setFilterDateRange] = useState([moment().subtract(1, 'days'),moment()])
const [operationsData, setOperationsData] = useState([])
const [loader, setLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const disabledDate = (current) => current < avilableDatesRange[0] || current > avilableDatesRange[1]
useEffect(() => invokeWebApiWrapperAsync(
diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx
index e37da57..460ccd1 100755
--- a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx
+++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx
@@ -1,5 +1,5 @@
import { memo } from 'react'
-export const TelemetryAnalysisOperationsToInterval = memo(({ idWell }) => (<>{idWell} 123>))
+export const TelemetryAnalysisOperationsToInterval = memo(() => (<>123>))
export default TelemetryAnalysisOperationsToInterval
diff --git a/src/pages/TelemetryAnalysis/index.jsx b/src/pages/TelemetryAnalysis/index.jsx
index 1cd423c..54bae03 100755
--- a/src/pages/TelemetryAnalysis/index.jsx
+++ b/src/pages/TelemetryAnalysis/index.jsx
@@ -1,24 +1,26 @@
-import { memo } from 'react'
-import { Layout } from 'antd'
+import { useParams } from 'react-router-dom'
+import { memo, useContext, useMemo } from 'react'
import { FolderOutlined } from '@ant-design/icons'
-import { Switch, useParams } from 'react-router-dom'
+import { Layout } from 'antd'
-import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private'
+import { PrivateMenu, PrivateSwitch } from '@components/Private'
import TelemetryAnalysisDepthToDay from './TelemetryAnalysisDepthToDay'
import TelemetryAnalysisDepthToInterval from './TelemetryAnalysisDepthToInterval'
import TelemetryAnalysisOperationsSummary from './TelemetryAnalysisOperationsSummary'
import TelemetryAnalysisOperationsToInterval from './TelemetryAnalysisOperationsToInterval'
+import { RootPathContext } from '@pages/Main'
const { Content } = Layout
-export const TelemetryAnalysis = memo(({ idWell }) => {
+export const TelemetryAnalysis = memo(() => {
const { tab } = useParams()
- const rootPath = `/well/${idWell}/telemetryAnalysis`
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/telemetryAnalysis`, [root])
return (
- <>
-
+
+
} key={'depthToDay'} title={'Глубина-день'} />
} key={'depthToInterval'} title={'Глубина-интервал'} />
} key={'operationsSummary'} title={'Все операции'} />
@@ -27,29 +29,15 @@ export const TelemetryAnalysis = memo(({ idWell }) => {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
- >
+
)
})
diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx
index 41bae5e..f3aa58c 100755
--- a/src/pages/Well.jsx
+++ b/src/pages/Well.jsx
@@ -1,4 +1,4 @@
-import { memo, useMemo } from 'react'
+import { createContext, memo, useContext, useMemo } from 'react'
import {
FolderOutlined,
FundViewOutlined,
@@ -7,9 +7,9 @@ import {
DeploymentUnitOutlined,
} from '@ant-design/icons'
import { Layout } from 'antd'
-import { Switch, useParams } from 'react-router-dom'
+import { useParams } from 'react-router-dom'
-import { PrivateRoute, PrivateDefaultRoute, PrivateMenu } from '@components/Private'
+import { PrivateMenu, PrivateSwitch } from '@components/Private'
import Report from './Report'
import Measure from './Measure'
@@ -19,69 +19,51 @@ import Telemetry from './Telemetry'
import WellOperations from './WellOperations'
import DrillingProgram from './DrillingProgram'
import TelemetryAnalysis from './TelemetryAnalysis'
+import { RootPathContext } from './Main'
import '@styles/index.css'
const { Content } = Layout
+export const IdWellContext = createContext(null)
+
export const Well = memo(() => {
const { idWell, tab } = useParams()
- const rootPath = useMemo(() => `/well/${idWell}`, [idWell])
+ const root = useContext(RootPathContext)
+ const rootPath = useMemo(() => `${root}/well/${idWell}`, [root, idWell])
return (
-
-
- } title={'Телеметрия'}/>
- } title={'Рапорт'} />
- } title={'Аналитика'} />
- } title={'Операции по скважине'} />
- {/* } title={'Операции по телеметрии'} /> */}
- } title={'Документы'} />
- } title={'Измерения'} />
- } title={'Программа бурения'} />
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ } title={'Телеметрия'}/>
+ } title={'Рапорт'} />
+ } title={'Аналитика'} />
+ } title={'Операции по скважине'} />
+ {/* } title={'Операции по телеметрии'} /> */}
+ } title={'Документы'} />
+ } title={'Измерения'} />
+ } title={'Программа бурения'} />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
)
})
diff --git a/src/pages/WellOperations/DrillProcessFlow.jsx b/src/pages/WellOperations/DrillProcessFlow.jsx
index 878d410..b451c25 100755
--- a/src/pages/WellOperations/DrillProcessFlow.jsx
+++ b/src/pages/WellOperations/DrillProcessFlow.jsx
@@ -1,4 +1,4 @@
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
import {
EditableTable,
@@ -11,6 +11,8 @@ import { invokeWebApiWrapperAsync } from '@components/factory'
import { hasPermission } from '@utils/permissions'
import { arrayOrDefault } from '@utils'
+import { IdWellContext } from '../Well'
+
const columns = [
makeNumericStartEnd('Глубина, м', 'depth'),
makeNumericMinMax('Нагрузка, т', 'axialLoad'),
@@ -20,10 +22,12 @@ const columns = [
makeNumericMinMax('Расход, л/с', 'flow')
]
-export const DrillProcessFlow = memo(({ idWell }) => {
+export const DrillProcessFlow = memo(() => {
const [flows, setFlows] = useState([])
const [showLoader, setShowLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const updateFlows = () => invokeWebApiWrapperAsync(
async () => {
const flows = await DrillFlowChartService.get(idWell)
diff --git a/src/pages/WellOperations/Tvd/index.jsx b/src/pages/WellOperations/Tvd/index.jsx
index c35a2d3..6f61e78 100755
--- a/src/pages/WellOperations/Tvd/index.jsx
+++ b/src/pages/WellOperations/Tvd/index.jsx
@@ -1,5 +1,5 @@
import { useHistory } from 'react-router-dom'
-import { memo, useState, useRef, useEffect, useCallback } from 'react'
+import { memo, useState, useRef, useEffect, useCallback, useContext, useMemo } from 'react'
import { DoubleLeftOutlined, DoubleRightOutlined } from '@ant-design/icons'
import { Switch, Button } from 'antd'
@@ -27,6 +27,7 @@ import AdditionalTables from './AdditionalTables'
import '@styles/index.css'
import '@styles/tvd.less'
+import { IdWellContext } from '@asb/pages/Well'
Chart.register(
TimeScale,
@@ -114,13 +115,16 @@ const makeDataset = (data, label, color, borderWidth = 1.5, borderDash) => ({
borderDash,
})
-export const Tvd = memo(({ idWell, title, ...other }) => {
+export const Tvd = memo(({ idWell: wellId, title, ...other }) => {
const [chart, setChart] = useState()
const [xLabel, setXLabel] = useState('day')
const [operations, setOperations] = useState({})
const [tableVisible, setTableVisible] = useState(false)
const [isLoading, setIsLoading] = useState(false)
+ const idWellContext = useContext(IdWellContext)
+ const idWell = useMemo(() => wellId ?? idWellContext, [wellId, idWellContext])
+
const chartRef = useRef(null)
const history = useHistory()
diff --git a/src/pages/WellOperations/WellDrillParams.jsx b/src/pages/WellOperations/WellDrillParams.jsx
index b113209..79b7e63 100755
--- a/src/pages/WellOperations/WellDrillParams.jsx
+++ b/src/pages/WellOperations/WellDrillParams.jsx
@@ -1,4 +1,4 @@
-import { useState, useEffect, useCallback, memo, useMemo } from 'react'
+import { useState, useEffect, useCallback, memo, useMemo, useContext } from 'react'
import {
EditableTable,
@@ -13,6 +13,8 @@ import { DrillParamsService, WellOperationService } from '@api'
import { hasPermission } from '@utils/permissions'
import { arrayOrDefault } from '@utils'
+import { IdWellContext } from '../Well'
+
export const getColumns = async (idWell) => {
let sectionTypes = await WellOperationService.getSectionTypes(idWell)
sectionTypes = Object.entries(sectionTypes).map(([id, value]) => ({
@@ -34,11 +36,13 @@ export const getColumns = async (idWell) => {
]
}
-export const WellDrillParams = memo(({ idWell }) => {
+export const WellDrillParams = memo(() => {
const [params, setParams] = useState([])
const [showLoader, setShowLoader] = useState(false)
const [columns, setColumns] = useState([])
+ const idWell = useContext(IdWellContext)
+
const updateParams = useCallback(async () => await invokeWebApiWrapperAsync(
async () => {
const params = arrayOrDefault(await DrillParamsService.getAll(idWell))
diff --git a/src/pages/WellOperations/WellOperationsEditor.jsx b/src/pages/WellOperations/WellOperationsEditor.jsx
index 033a6f0..6c50d0f 100755
--- a/src/pages/WellOperations/WellOperationsEditor.jsx
+++ b/src/pages/WellOperations/WellOperationsEditor.jsx
@@ -1,7 +1,7 @@
import moment from 'moment'
import { Input } from 'antd'
import { useLocation } from 'react-router-dom'
-import { useState, useEffect, memo, useMemo, useCallback } from 'react'
+import { useState, useEffect, memo, useMemo, useCallback, useContext } from 'react'
import {
EditableTable,
@@ -21,6 +21,8 @@ import { hasPermission } from '@utils/permissions'
import { arrayOrDefault } from '@utils'
import { WellOperationService } from '@api'
+import { IdWellContext } from '../Well'
+
const { TextArea } = Input
const basePageSize = 160
@@ -52,12 +54,14 @@ const generateColumns = (showNpt = false, categories = [], sectionTypes = []) =>
makeTextColumn('Комментарий', 'comment', null, null, null, { editable: true, input: }),
].filter(Boolean)
-export const WellOperationsEditor = memo(({ idWell, idType, showNpt, ...other }) => {
+export const WellOperationsEditor = memo(({ idType, showNpt, ...other }) => {
const [pageNumAndPageSize, setPageNumAndPageSize] = useState({ current: 1, pageSize: basePageSize })
const [paginationTotal, setPaginationTotal] = useState(0)
const [operations, setOperations] = useState([])
const [showLoader, setShowLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
const [categories, setCategories] = useState([])
const [sectionTypes, setSectionTypes] = useState([])
diff --git a/src/pages/WellOperations/WellSectionsStat.jsx b/src/pages/WellOperations/WellSectionsStat.jsx
index 5355698..8afa41e 100755
--- a/src/pages/WellOperations/WellSectionsStat.jsx
+++ b/src/pages/WellOperations/WellSectionsStat.jsx
@@ -1,10 +1,12 @@
-import { useState, useEffect, memo } from 'react'
+import { useState, useEffect, memo, useContext } from 'react'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { Table, makeColumn, makeColumnsPlanFact, makeNumericRender } from '@components/Table'
-import { OperationStatService } from '@api'
import { calcDuration } from '@utils/datetime'
+import { OperationStatService } from '@api'
+
+import { IdWellContext } from '../Well'
const numericRender = makeNumericRender(2)
@@ -19,10 +21,12 @@ const columns = [
makeColumnsPlanFact('Спуск ОК, м/ч' ,'casingDownSpeed', { render: numericRender }),
]
-export const WellSectionsStat = memo(({ idWell }) => {
+export const WellSectionsStat = memo(() => {
const [sections, setSections] = useState([])
const [showLoader, setShowLoader] = useState(false)
+ const idWell = useContext(IdWellContext)
+
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const sectionsResponse = await OperationStatService.getStatWell(idWell)
diff --git a/src/pages/WellOperations/index.jsx b/src/pages/WellOperations/index.jsx
index 5e14dd3..c807f08 100755
--- a/src/pages/WellOperations/index.jsx
+++ b/src/pages/WellOperations/index.jsx
@@ -1,6 +1,6 @@
-import { memo, useCallback } from 'react'
+import { useParams, useHistory, useLocation } from 'react-router-dom'
+import { memo, useCallback, useContext, useMemo } from 'react'
import { Layout } from 'antd'
-import { Switch, useParams, useHistory, useLocation } from 'react-router-dom'
import {
BarChartOutlined,
BuildOutlined,
@@ -9,7 +9,7 @@ import {
TableOutlined,
} from '@ant-design/icons'
-import { PrivateDefaultRoute, PrivateRoute, PrivateMenu } from '@components/Private'
+import { PrivateMenu, PrivateSwitch } from '@components/Private'
import { Tvd } from './Tvd'
import { ImportExportBar } from './ImportExportBar'
@@ -17,26 +17,31 @@ import { WellDrillParams } from './WellDrillParams'
import { DrillProcessFlow } from './DrillProcessFlow'
import { WellSectionsStat } from './WellSectionsStat'
import { WellOperationsEditor } from './WellOperationsEditor'
-import { Flex } from '@asb/components/Grid'
+import { Flex } from '@components/Grid'
+
+import { RootPathContext } from '@pages/Main'
+import { IdWellContext } from '@pages/Well'
const { Content } = Layout
-export const WellOperations = memo(({ idWell }) => {
+export const WellOperations = memo(() => {
const { tab } = useParams()
const history = useHistory()
const location = useLocation()
- const rootPath = `/well/${idWell}/operations`
+ const root = useContext(RootPathContext)
+ const idWell = useContext(IdWellContext)
+ const rootPath = useMemo(() => `${root}/operations`, [root])
const onImported = useCallback(() =>
history.push({ pathname: `${rootPath}`, state: { from: location.pathname }})
, [history, location, rootPath])
- const isIEBarDisabled = !['plan', 'fact'].includes(tab)
+ const isIEBarDisabled = useMemo(() => !['plan', 'fact'].includes(tab), [tab])
return(
- <>
+
-
+
} key={'tvd'} title={'TVD'} />
} key={'sections'} title={'Секции'} />
} key={'plan'} title={'План'} />
@@ -48,37 +53,17 @@ export const WellOperations = memo(({ idWell }) => {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
- >
+
)
})