From 777fbb63d1f751db05b3d54faa83abfe7e3e8775 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Fri, 18 Mar 2022 19:40:52 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BC=D0=B5=D0=BC=D0=BE=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/AdminPanel/ClusterController.jsx | 18 +++-- src/pages/AdminPanel/CompanyController.jsx | 13 ++-- .../AdminPanel/CompanyTypeController.jsx | 13 ++-- src/pages/AdminPanel/DepositController.jsx | 18 +++-- src/pages/AdminPanel/PermissionController.jsx | 16 ++--- src/pages/AdminPanel/RoleController.jsx | 46 ++++++------ src/pages/AdminPanel/TelemetryController.jsx | 36 +++++----- src/pages/AdminPanel/UserController/index.jsx | 8 +-- src/pages/AdminPanel/VisitLog.jsx | 20 +++--- src/pages/AdminPanel/WellController/index.jsx | 20 +++--- .../WellCompositeSections.jsx | 42 ++++++----- src/pages/Analytics/index.jsx | 4 +- src/pages/Archive/ArchiveColumn.jsx | 25 +++---- src/pages/Archive/ArchiveDisplay.jsx | 14 ++-- src/pages/Archive/index.jsx | 15 ++-- src/pages/Cluster/ClusterWells.jsx | 6 +- src/pages/Cluster/WellOperationsTable.jsx | 23 +++--- src/pages/Cluster/index.jsx | 6 +- src/pages/Documents/DocumentsTemplate.jsx | 70 +++++++------------ src/pages/Documents/index.jsx | 4 +- src/pages/DrillingProgram/CategoryEditor.jsx | 6 +- src/pages/DrillingProgram/CategoryRender.jsx | 4 +- src/pages/DrillingProgram/index.jsx | 18 ++--- src/pages/Login.jsx | 3 +- src/pages/Measure/InclinometryTable.jsx | 13 ++-- src/pages/Measure/MeasureTable.jsx | 29 ++++---- src/pages/Messages.jsx | 8 +-- src/pages/Report/index.jsx | 10 +-- src/pages/Well.jsx | 4 +- src/pages/WellOperations/WellDrillParams.jsx | 8 +-- .../WellOperations/WellOperationsEditor.jsx | 4 +- 31 files changed, 231 insertions(+), 293 deletions(-) diff --git a/src/pages/AdminPanel/ClusterController.jsx b/src/pages/AdminPanel/ClusterController.jsx index dc8117d..0da72f5 100644 --- a/src/pages/AdminPanel/ClusterController.jsx +++ b/src/pages/AdminPanel/ClusterController.jsx @@ -21,10 +21,16 @@ import { coordsFixed } from './DepositController' export const ClusterController = memo(() => { const [deposits, setDeposits] = useState([]) const [clusters, setClusters] = useState([]) - const [filteredClusters, setFilteredClusters] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredClusters = useMemo(() => clusters.filter((cluster) => cluster && (!searchValue || [ + cluster.caption ?? '', + cluster.latitude?.toString ?? '', + cluster.longitude?.toString() ?? '', + ].join(' ').toLowerCase().includes(searchValue.toLowerCase())) + ), [clusters, searchValue]) + const clusterColumns = useMemo(() => [ makeSelectColumn('Месторождение', 'idDeposit', deposits, '--', { width: 200, @@ -65,14 +71,6 @@ export const ClusterController = memo(() => { useEffect(updateTable, [updateTable]) - useEffect(() => { - setFilteredClusters(clusters.filter((cluster) => cluster && (!searchValue || [ - cluster.caption ?? '', - cluster.latitude?.toString ?? '', - cluster.longitude?.toString() ?? '', - ].join(' ').toLowerCase().includes(searchValue.toLowerCase())))) - }, [clusters, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminClusterService, setLoader: setShowLoader, @@ -84,7 +82,7 @@ export const ClusterController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/CompanyController.jsx b/src/pages/AdminPanel/CompanyController.jsx index c2c5923..836ab11 100644 --- a/src/pages/AdminPanel/CompanyController.jsx +++ b/src/pages/AdminPanel/CompanyController.jsx @@ -19,10 +19,13 @@ import { hasPermission } from '@utils/permissions' export const CompanyController = memo(() => { const [columns, setColumns] = useState([]) const [companies, setCompanies] = useState([]) - const [filteredCompanies, setFilteredCompanies] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredCompanies = useMemo(() => companies.filter((company) => company && (!searchValue || + company.caption?.toLowerCase()?.includes(searchValue.toLowerCase()) + )), [companies, searchValue]) + const updateTable = useCallback(async () => { const companies = await AdminCompanyService.getAll() setCompanies(arrayOrDefault(companies)) @@ -55,12 +58,6 @@ export const CompanyController = memo(() => { 'Получение списка типов команд' ), [updateTable]) - useEffect(() => { - setFilteredCompanies(companies.filter((company) => company && (!searchValue || - company.caption?.toLowerCase()?.includes(searchValue.toLowerCase()) - ))) - }, [companies, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminCompanyService, setLoader: setShowLoader, @@ -77,7 +74,7 @@ export const CompanyController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/CompanyTypeController.jsx b/src/pages/AdminPanel/CompanyTypeController.jsx index 7e117f6..0fa804d 100644 --- a/src/pages/AdminPanel/CompanyTypeController.jsx +++ b/src/pages/AdminPanel/CompanyTypeController.jsx @@ -25,10 +25,13 @@ const columns = [ export const CompanyTypeController = memo(() => { const [companyTypes, setCompanyTypes] = useState([]) - const [filteredCompanyTypes, setFilteredCompanyTypes] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredCompanyTypes = useMemo(() => companyTypes.filter((companyType) => companyType && (!searchValue || + companyType.caption?.toLowerCase()?.includes(searchValue.toLowerCase()) + )), [companyTypes, searchValue]) + const updateTable = useCallback(() => invokeWebApiWrapperAsync( async() => { const companyTypes = await AdminCompanyTypeService.getAll() @@ -41,12 +44,6 @@ export const CompanyTypeController = memo(() => { useEffect(updateTable, [updateTable]) - useEffect(() => { - setFilteredCompanyTypes(companyTypes.filter((companyType) => companyType && (!searchValue || - companyType.caption?.toLowerCase()?.includes(searchValue.toLowerCase()) - ))) - }, [companyTypes, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminCompanyTypeService, setLoader: setShowLoader, @@ -58,7 +55,7 @@ export const CompanyTypeController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/DepositController.jsx b/src/pages/AdminPanel/DepositController.jsx index 30e9209..9a1b5e1 100644 --- a/src/pages/AdminPanel/DepositController.jsx +++ b/src/pages/AdminPanel/DepositController.jsx @@ -19,10 +19,16 @@ const depositColumns = [ export const DepositController = memo(() => { const [deposits, setDeposits] = useState([]) - const [filteredDeposits, setFilteredDeposits] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredDeposits = useMemo(() => deposits.filter((deposit) => deposit && (!searchValue || [ + deposit.caption ?? '', + deposit.latitude?.toString() ?? '', + deposit.longitude?.toString() ?? '', + ].join(' ').toLowerCase().includes(searchValue.toLowerCase())) + ), [deposits, searchValue]) + const updateTable = useCallback(() => invokeWebApiWrapperAsync( async() => { const deposits = await AdminDepositService.getAll() @@ -35,14 +41,6 @@ export const DepositController = memo(() => { useEffect(updateTable, [updateTable]) - useEffect(() => { - setFilteredDeposits(deposits.filter((deposit) => deposit && (!searchValue || [ - deposit.caption ?? '', - deposit.latitude?.toString() ?? '', - deposit.longitude?.toString() ?? '', - ].join(' ').toLowerCase().includes(searchValue.toLowerCase())))) - }, [deposits, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminDepositService, setLoader: setShowLoader, @@ -54,7 +52,7 @@ export const DepositController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/PermissionController.jsx b/src/pages/AdminPanel/PermissionController.jsx index d555995..8f1ecba 100644 --- a/src/pages/AdminPanel/PermissionController.jsx +++ b/src/pages/AdminPanel/PermissionController.jsx @@ -28,10 +28,15 @@ const columns = [ export const PermissionController = memo(() => { const [permissions, setPermissions] = useState([]) - const [filteredPermissions, setFilteredPermissions] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredPermissions = useMemo(() => permissions.filter((permission) => permission && (!searchValue || [ + permission.name ?? '', + permission.description ?? '', + ].join(' ').includes(searchValue.toLowerCase())) + ), [permissions, searchValue]) + const updateTable = useCallback(async () => invokeWebApiWrapperAsync( async () => { const permission = await AdminPermissionService.getAll() @@ -44,13 +49,6 @@ export const PermissionController = memo(() => { useEffect(() => updateTable(), [updateTable]) - useEffect(() => { - setFilteredPermissions(permissions.filter((permission) => permission && (!searchValue || [ - permission.name ?? '', - permission.description ?? '', - ].join(' ').includes(searchValue.toLowerCase())))) - }, [permissions, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminPermissionService, setLoader: setShowLoader, @@ -62,7 +60,7 @@ export const PermissionController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/RoleController.jsx b/src/pages/AdminPanel/RoleController.jsx index 13fd47d..102cf65 100644 --- a/src/pages/AdminPanel/RoleController.jsx +++ b/src/pages/AdminPanel/RoleController.jsx @@ -12,32 +12,32 @@ import { hasPermission } from '@utils/permissions' export const RoleController = memo(() => { const [permissions, setPermissions] = useState([]) const [roles, setRoles] = useState([]) - const [filteredRoles, setFilteredRoles] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') - const [columns, setColumns] = useState([]) + + const filteredRoles = useMemo(() => roles.filter((role) => role && (!searchValue || + role.caption?.toLowerCase()?.includes(searchValue.toLowerCase()) + )), [roles, searchValue]) + + const columns = useMemo(() => [ + makeTextColumn('Название', 'caption', null, null, null, { width: 100, editable: true, formItemRules: min1 }), + makeTagColumn('Включённые роли', 'roles', roles, 'id', 'caption', { + width: 400, + editable: true, + render: (role) => + }, { allowClear: true }), + makeTagColumn('Разрешения', 'permissions', permissions, 'id', 'name', { + width: 600, + editable: true, + render: (permission) => , + }), + ], [roles, permissions]) const loadRoles = useCallback(async () => { const roles = await AdminUserRoleService.getAll() setRoles(arrayOrDefault(roles)) }, []) - useEffect(() => { - setColumns([ - makeTextColumn('Название', 'caption', null, null, null, { width: 100, editable: true, formItemRules: min1 }), - makeTagColumn('Включённые роли', 'roles', roles, 'id', 'caption', { - width: 400, - editable: true, - render: (role) => - }, { allowClear: true }), - makeTagColumn('Разрешения', 'permissions', permissions, 'id', 'name', { - width: 600, - editable: true, - render: (permission) => , - }), - ]) - }, [roles, permissions]) - useEffect(() => invokeWebApiWrapperAsync( async () => { const permissions = await AdminPermissionService.getAll() @@ -49,12 +49,6 @@ export const RoleController = memo(() => { 'Получение списка ролей' ), [loadRoles]) - useEffect(() => { - setFilteredRoles(roles.filter((role) => role && (!searchValue || - role.caption?.toLowerCase()?.includes(searchValue.toLowerCase()) - ))) - }, [roles, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminUserRoleService, setLoader: setShowLoader, @@ -63,7 +57,7 @@ export const RoleController = memo(() => { loadRoles, setShowLoader, `Не удалось загрузить список ролей`, - 'Получение списка ролей' + 'Получение списка ролей', ) }), [loadRoles]) @@ -71,7 +65,7 @@ export const RoleController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/TelemetryController.jsx b/src/pages/AdminPanel/TelemetryController.jsx index 23283be..716d6e7 100644 --- a/src/pages/AdminPanel/TelemetryController.jsx +++ b/src/pages/AdminPanel/TelemetryController.jsx @@ -1,4 +1,4 @@ -import { memo, useEffect, useState } from 'react' +import { memo, useEffect, useMemo, useState } from 'react' import { Input } from 'antd' import { @@ -31,10 +31,24 @@ const columns = [ export const TelemetryController = memo(() => { const [telemetryData, setTelemetryData] = useState([]) - const [filteredTelemetryData, setFilteredTelemetryData] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredTelemetryData = useMemo(() => telemetryData.filter((telemetry) => telemetry && (!searchValue || [ + telemetry.id?.toString() ?? '', + telemetry.remoteUid ?? '', + telemetry.realWell ?? '', + telemetry.drillingStartDate ?? '', + telemetry.well ?? '', + telemetry.cluster ?? '', + telemetry.deposit ?? '', + telemetry.customer ?? '', + telemetry.comment ?? '', + telemetry.hmiVersion ?? '', + telemetry.saubPlcVersion ?? '', + telemetry.spinPlcVersion ?? '', + ].join(' ').toLowerCase().includes(searchValue.toLowerCase())) + ), [telemetryData, searchValue]) useEffect(() => invokeWebApiWrapperAsync( async () => { @@ -51,27 +65,11 @@ export const TelemetryController = memo(() => { 'Полученик списка телеметрии скважин' ), []) - useEffect(() => { - setFilteredTelemetryData(telemetryData.filter((telemetry) => telemetry && (!searchValue || [ - telemetry.remoteUid ?? '', - telemetry.realWell ?? '', - telemetry.drillingStartDate ?? '', - telemetry.well ?? '', - telemetry.cluster ?? '', - telemetry.deposit ?? '', - telemetry.customer ?? '', - telemetry.comment ?? '', - telemetry.hmiVersion ?? '', - telemetry.saubPlcVersion ?? '', - telemetry.spinPlcVersion ?? '', - ].join(' ').toLowerCase().includes(searchValue.toLowerCase())))) - }, [telemetryData, searchValue]) - return ( <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} diff --git a/src/pages/AdminPanel/UserController/index.jsx b/src/pages/AdminPanel/UserController/index.jsx index 528973b..2152cd4 100644 --- a/src/pages/AdminPanel/UserController/index.jsx +++ b/src/pages/AdminPanel/UserController/index.jsx @@ -1,6 +1,6 @@ import { Button, Input, Tag } from 'antd' import { UserSwitchOutlined } from '@ant-design/icons' -import { memo, useCallback, useEffect, useState } from 'react' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' import { BehaviorSubject, debounceTime, distinctUntilChanged, filter, map } from 'rxjs' import { @@ -172,12 +172,12 @@ export const UserController = memo(() => { 'Получение списка компаний' ), []) - const handlerProps = { + const handlerProps = useMemo(() => ({ service: AdminUserService, setLoader: setShowLoader, errorMsg: `Не удалось выполнить операцию`, onComplete: updateTable, - } + }), [updateTable]) const onSearchTextChange = useCallback((e) => subject?.next(e?.target?.value), [subject]) @@ -186,7 +186,7 @@ export const UserController = memo(() => { formatDate(date, false, 'DD MMM YYYY, HH:mm:ss'), + render: (date) => formatDate(date, false), sorter: makeDateSorter('lastDate'), }), ] export const VisitLog = memo(() => { const [logData, setLogData] = useState([]) - const [filteredLogData, setFilteredLogData] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredLogData = useMemo(() => logData.filter((data) => data && (!searchValue || [ + data.login ?? '', + data.ip ?? '', + data.lastDate ?? '', + ].join(' ').toLowerCase().includes(searchValue.toLowerCase())) + ), [logData, searchValue]) + useEffect(() => invokeWebApiWrapperAsync( async () => { const logData = arrayOrDefault(await RequestTrackerService.getUsersStat(logRecordCount)) @@ -34,14 +40,6 @@ export const VisitLog = memo(() => { 'Получение списка последних посещений' ), []) - useEffect(() => { - setFilteredLogData(logData.filter((data) => data && (!searchValue || [ - data.login ?? '', - data.ip ?? '', - data.lastDate ?? '', - ].join(' ').toLowerCase().includes(searchValue.toLowerCase())))) - }, [logData, searchValue]) - return ( <> ({ export const WellController = memo(() => { const [columns, setColumns] = useState([]) const [wells, setWells] = useState([]) - const [filteredWells, setFilteredWells] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const filteredWells = useMemo(() => wells.filter((well) => well && (!searchValue || [ + well.caption ?? '', + well.latitude?.toString() ?? '', + well.longitude?.toString() ?? '', + ].join(' ').toLowerCase().includes(searchValue.toLowerCase())) + ), [wells, searchValue]) + const updateTable = useCallback(async () => invokeWebApiWrapperAsync( async () => { @@ -116,14 +122,6 @@ export const WellController = memo(() => { 'Получение списка кустов' ), [updateTable]) - useEffect(() => { - setFilteredWells(wells.filter((well) => well && (!searchValue || [ - well.caption ?? '', - well.latitude?.toString() ?? '', - well.longitude?.toString() ?? '', - ].join(' ').toLowerCase().includes(searchValue.toLowerCase())))) - }, [wells, searchValue]) - const handlerProps = useMemo(() => ({ service: AdminWellService, setLoader: setShowLoader, @@ -135,14 +133,14 @@ export const WellController = memo(() => { <> setSearchValue(e.target.value)} value={searchValue} loading={showLoader} /> { - const [rows, setRows] = useState([]) const [params, setParams] = useState([]) - const [paramsColumns, setParamsColumns] = useState([]) const [selectedWells, setSelectedWells] = useState([]) const [wellOperations, setWellOperations] = useState([]) const [selectedWellsKeys, setSelectedWellsKeys] = useState([]) @@ -44,21 +42,9 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection const location = useLocation() - useEffect(() => (async() => setParamsColumns(await getColumns(idWell)))(), [idWell]) + const paramsColumns = useMemo(async() => await getColumns(idWell), [idWell]) - useEffect(() => { - if (isOpsModalVisible || selectedWellId <= 0) return - invokeWebApiWrapperAsync( - async () => { - const { operations } = await getOperations(selectedWellId) - setWellOperations(operations) - }, - setShowLoader, - `Не удалось загрузить операции по скважине "${selectedWellId}"`, - ) - }, [selectedWellId, isOpsModalVisible]) - - useEffect(() => { + const rows = useMemo(() => { const rows = [] statsWells?.forEach((well) => { well.sections?.forEach((section) => { @@ -113,9 +99,21 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection 'nonProductiveTimeFact', ]) - setRows(rows) + return rows }, [statsWells]) + useEffect(() => { + if (isOpsModalVisible || selectedWellId <= 0) return + invokeWebApiWrapperAsync( + async () => { + const { operations } = await getOperations(selectedWellId) + setWellOperations(operations) + }, + setShowLoader, + `Не удалось загрузить операции по скважине "${selectedWellId}"`, + ) + }, [selectedWellId, isOpsModalVisible]) + useEffect(() => { const selected = rows.filter((row) => selectedSections.some(section => ( section.idWellSrc === row.id && section.idWellSectionType === row.sectionId @@ -125,7 +123,7 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection setSelectedWellsKeys(selected.map((row) => row.key)) }, [rows, selectedSections]) - const columns = [ + const columns = useMemo(() => [ makeTextColumn('скв №', 'caption', null, null, (text, item) => {text ?? '-'} ), @@ -171,9 +169,9 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection )) ?? '-', }, - ] + ], [location.pathname]) - const rowSelection = hasPermission('WellOperation.edit') && { + const rowSelection = useMemo(() => hasPermission('WellOperation.edit') && { selectedRowKeys: selectedWellsKeys, onChange: (keys, items) => invokeWebApiWrapperAsync( async () => { @@ -187,7 +185,7 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection `Не удалось сохранить изменения выбранных секций для композитной скважины "${idWell}"`, 'Изменение выбранных секций скважины' ) - } + }, [idWell, selectedWellsKeys]) const onParamButtonClick = useCallback(() => invokeWebApiWrapperAsync( async () => { diff --git a/src/pages/Analytics/index.jsx b/src/pages/Analytics/index.jsx index 6e18f36..bac5683 100644 --- a/src/pages/Analytics/index.jsx +++ b/src/pages/Analytics/index.jsx @@ -1,4 +1,4 @@ -import { memo } from 'react' +import { memo, useMemo } from 'react' import { Layout, Menu } from 'antd' import { Switch, useParams } from 'react-router-dom' @@ -9,7 +9,7 @@ import Statistics from './Statistics' export const Analytics = memo(({ idWell }) => { const { tab } = useParams() - const rootPath = `/well/${idWell}/analytics` + const rootPath = useMemo(() => `/well/${idWell}/analytics`, [idWell]) return ( diff --git a/src/pages/Archive/ArchiveColumn.jsx b/src/pages/Archive/ArchiveColumn.jsx index 5e211e1..6f7ebfb 100644 --- a/src/pages/Archive/ArchiveColumn.jsx +++ b/src/pages/Archive/ArchiveColumn.jsx @@ -1,21 +1,14 @@ -import { useEffect, useState } from 'react' +import { memo, useMemo } from 'react' import { Grid, GridItem } from '@components/Grid' import { Column } from '@components/charts/Column' -export const ArchiveColumn = ({ lineGroup, data, interval, style, headerHeight, yStart }) => { - const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) - const [pv, setPV] = useState([]) - - useEffect(() => { - const lgws = lineGroup.filter(cfg => !cfg.isShape) - setLineGroupWithoutShapes(lgws) - setPV(lgws.filter(line => line.showLabels).map(line => ({ - color: line.color, - label: line.label - }))) - }, [lineGroup]) - +export const ArchiveColumn = memo(({ lineGroup, data, interval, style, headerHeight, yStart }) => { + const lgws = useMemo(() => lineGroup.filter(cfg => !cfg.isShape), [lineGroup]) + const pv = useMemo(() => lgws.filter(line => line.showLabels).map(line => ({ + color: line.color, + label: line.label + })), [lgws]) return (
@@ -26,13 +19,13 @@ export const ArchiveColumn = ({ lineGroup, data, interval, style, headerHeight,
) -} +}) export default ArchiveColumn diff --git a/src/pages/Archive/ArchiveDisplay.jsx b/src/pages/Archive/ArchiveDisplay.jsx index 3b9cef3..c4bae7e 100644 --- a/src/pages/Archive/ArchiveDisplay.jsx +++ b/src/pages/Archive/ArchiveDisplay.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { memo, useMemo } from 'react' import { Grid, GridItem } from '@components/Grid' @@ -41,13 +41,9 @@ export const cutData = (data, beginDate, endDate) => { return data } -export const ArchiveDisplay = ({data, startDate, interval, onWheel}) => { - const [chartData, setChartData] = useState([]) - - useEffect(() => { - const endDate = new Date(+startDate + interval) - setChartData(cutData(data, startDate, endDate)) - }, [data, startDate, interval]) +export const ArchiveDisplay = memo(({data, startDate, interval, onWheel}) => { + const endDate = useMemo(() => new Date(+startDate + interval), [startDate, interval]) + const chartData = useMemo(() => cutData(data, startDate, endDate), [data, startDate, endDate]) return ( @@ -65,6 +61,6 @@ export const ArchiveDisplay = ({data, startDate, interval, onWheel}) => { ))} ) -} +}) export default ArchiveDisplay diff --git a/src/pages/Archive/index.jsx b/src/pages/Archive/index.jsx index f15ec85..7ee7375 100644 --- a/src/pages/Archive/index.jsx +++ b/src/pages/Archive/index.jsx @@ -1,5 +1,5 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useCallback } from 'react' import { Flex } from '@components/Grid' import LoaderPortal from '@components/LoaderPortal' @@ -69,7 +69,7 @@ export const Archive = memo(({ idWell }) => { const [showLoader, setShowLoader] = useState(false) const [loaded, setLoaded] = useState(null) - const onGraphWheel = (e) => { + const onGraphWheel = useCallback((e) => { if (loaded && dateLimit.from && dateLimit.to) { setStartDate((prevStartDate) => { const offset = e.deltaY * chartInterval * WHEEL_SENSITIVITY @@ -79,14 +79,15 @@ export const Archive = memo(({ idWell }) => { return new Date(Math.max(firstPossibleDate, Math.min(nextStartDate, lastPossibleDate))) }) } - } + }, [loaded, dateLimit, chartInterval]) - const isDateDisabled = (date) => { + const isDateDisabled = useCallback((date) => { if (!date) return false const dt = new Date(date).setHours(0, 0, 0, 0) return dt < dateLimit.from || dt > +dateLimit.to - chartInterval - } - const isDateTimeDisabled = (date) => ({ + }, [dateLimit]) + + const isDateTimeDisabled = useCallback((date) => ({ disabledHours: () => range(0, 24).filter(h => { if (!date) return false const dt = +new Date(date).setHours(h) @@ -102,7 +103,7 @@ export const Archive = memo(({ idWell }) => { const dt = +new Date(date).setSeconds(s) return dt < dateLimit.from || dt > +dateLimit.to - chartInterval }) - }) + }), [dateLimit]) useEffect(() => invokeWebApiWrapperAsync( async () => { diff --git a/src/pages/Cluster/ClusterWells.jsx b/src/pages/Cluster/ClusterWells.jsx index 224b44d..f919f2f 100644 --- a/src/pages/Cluster/ClusterWells.jsx +++ b/src/pages/Cluster/ClusterWells.jsx @@ -1,5 +1,5 @@ import { Link, useLocation } from 'react-router-dom' -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useMemo } from 'react' import { Tag, Button, Modal } from 'antd' import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons' @@ -108,7 +108,7 @@ export const ClusterWells = memo(({ statsWells }) => { setTableData(data) }, [statsWells]) - const columns = [ + const columns = useMemo(() => [ makeTextColumn('скв №', 'caption', null, null, (_, item) => ( @@ -159,7 +159,7 @@ export const ClusterWells = memo(({ statsWells }) => { )) ?? '-', }, - ] + ], [location.pathname]) return ( <> diff --git a/src/pages/Cluster/WellOperationsTable.jsx b/src/pages/Cluster/WellOperationsTable.jsx index d23f8ae..b7f1692 100644 --- a/src/pages/Cluster/WellOperationsTable.jsx +++ b/src/pages/Cluster/WellOperationsTable.jsx @@ -1,18 +1,19 @@ +import { memo, useMemo } from 'react' import { Table } from 'antd' import { makeTextColumn, makeNumericColumnPlanFact } from '@components/Table' import { getPrecision } from '@utils/functions' -export const WellOperationsTable = ({ wellOperations }) => { - const columns = [ - makeTextColumn('Конструкция секции','sectionType'), - makeTextColumn('Операция','operationName'), - makeNumericColumnPlanFact('Глубина забоя', 'depth', null, null, getPrecision), - makeNumericColumnPlanFact('Часы', 'durationHours', null, null, getPrecision), - makeNumericColumnPlanFact('Комментарий', 'comment', null, null, (text) => text ?? '-') - ] +const columns = [ + makeTextColumn('Конструкция секции', 'sectionType'), + makeTextColumn('Операция', 'operationName'), + makeNumericColumnPlanFact('Глубина забоя', 'depth', null, null, getPrecision), + makeNumericColumnPlanFact('Часы', 'durationHours', null, null, getPrecision), + makeNumericColumnPlanFact('Комментарий', 'comment', null, null, (text) => text ?? '-') +] - const operations = wellOperations?.map(el => ({ +export const WellOperationsTable = memo(({ wellOperations }) => { + const operations = useMemo(() => wellOperations?.map(el => ({ key: el.plan?.id ?? el.fact.id, sectionType: el.plan?.wellSectionTypeName ?? el.fact?.wellSectionTypeName, operationName: `${el.plan?.categoryName ?? el.fact?.categoryName ?? ''} ${' '} @@ -23,7 +24,7 @@ export const WellOperationsTable = ({ wellOperations }) => { durationHoursFact: el.fact?.durationHours, commentPlan: el.plan?.comment ?? '-', commentFact: el.fact?.comment ?? '-' - })) + })), [wellOperations]) return ( { tableName={'well_operations'} /> ) -} +}) export default WellOperationsTable diff --git a/src/pages/Cluster/index.jsx b/src/pages/Cluster/index.jsx index 0b334b9..99e060f 100644 --- a/src/pages/Cluster/index.jsx +++ b/src/pages/Cluster/index.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, memo } from 'react' import { useParams } from 'react-router-dom' import { arrayOrDefault } from '@utils' @@ -8,7 +8,7 @@ import { invokeWebApiWrapperAsync } from '@components/factory' import ClusterWells from './ClusterWells' -export const Cluster = () => { +export const Cluster = memo(() => { const { idCluster } = useParams() const [data, setData] = useState([]) const [showLoader, setShowLoader] = useState(false) @@ -28,6 +28,6 @@ export const Cluster = () => { ) -} +}) export default Cluster diff --git a/src/pages/Documents/DocumentsTemplate.jsx b/src/pages/Documents/DocumentsTemplate.jsx index d25ee42..f786551 100644 --- a/src/pages/Documents/DocumentsTemplate.jsx +++ b/src/pages/Documents/DocumentsTemplate.jsx @@ -1,14 +1,13 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useMemo, useCallback } from 'react' import { DatePicker, Button, Input } from 'antd' import { FileService } from '@api' -import { hasPermission } from '@utils/permissions' import LoaderPortal from '@components/LoaderPortal' import { UploadForm } from '@components/UploadForm' import { CompanyView, UserView } from '@components/views' -import { EditableTable, makePaginationObject } from '@components/Table' +import { EditableTable, makeColumn, makeDateColumn, makeNumericColumn, makePaginationObject } from '@components/Table' import { invokeWebApiWrapperAsync, downloadFile, formatBytes } from '@components/factory' -import { formatDate } from '@utils' +import { hasPermission } from '@utils/permissions' const pageSize = 12 const { RangePicker } = DatePicker @@ -24,26 +23,11 @@ const columns = [ {name} ), - }, { - title: 'Дата загрузки', - key: 'uploadDate', - dataIndex: 'uploadDate', - render: item => formatDate(item, false, 'DD MMM YYYY, HH:mm:ss'), - }, { - title: 'Размер', - key: 'size', - dataIndex: 'size', - render: item => formatBytes(item) - }, { - title: 'Автор', - key: 'author', - dataIndex: 'author', - render: item => - }, { - title: 'Компания', - key: 'company', - render: (_, record) => - } + }, + makeDateColumn('Дата загрузки', 'uploadDate'), + makeNumericColumn('Размер', 'size', null, null, formatBytes), + makeColumn('Автор', 'author', { render: item => }), + makeColumn('Компания', 'company', { render: (_, record) => }) ] export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, customColumns, beforeTable, onChange, tableName }) => { @@ -55,21 +39,13 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus const [files, setFiles] = useState([]) const [showLoader, setShowLoader] = useState(false) - const uploadUrl = `/api/well/${idWell}/files/?idCategory=${idCategory}` + const uploadUrl = useMemo(() => `/api/well/${idWell}/files/?idCategory=${idCategory}`, [idWell, idCategory]) - const handleUploadComplete = () => update() + const mergedColumns = useMemo(() => [...columns, ...(customColumns ?? [])], [customColumns]) + const companies = useMemo(() => [...new Set(files.map(file => file.company))].filter(company => company), [files]) + const filenames = useMemo(() => [...new Set(files.map(file => file.name))].filter(name => name), [files]) - const handleFileDelete = async (file) => { - await FileService.delete(idWell, file.id) - update() - } - - const hanleCompanySearch = (value, _) => setFilterCompanyName(value) - const hanleFileNameSearch = (value, _) => setFilterFileName(value) - - const mergedColumns = [...columns, ...(customColumns ?? [])] - - const update = () => { + const update = useCallback(() => { let begin = null let end = null if (filterDataRange?.length > 1) { @@ -101,13 +77,15 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus `Не удалось загрузить файлы по скважине "${idWell}"`, 'Загрузка файла по скважине' ) - } + }, [filterCompanyName, filterDataRange, filterFileName, idCategory, idWell, page]) - useEffect(update, [idWell, idCategory, page, filterDataRange, filterCompanyName, filterFileName]) + useEffect(update, [update]) useEffect(() => onChange?.(files), [files, onChange]) - const companies = [...new Set(files.map(file => file.company))].filter(company => company) - const filenames = [...new Set(files.map(file => file.name))].filter(name => name) + const handleFileDelete = useMemo(() => hasPermission(`File.edit${idCategory}`) && (async (file) => { + await FileService.delete(idWell, file.id) + update() + }), [idWell, idCategory, update]) return ( @@ -124,7 +102,7 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus {companies.map((company) => ( @@ -138,7 +116,7 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus {filenames.map((name) => ( @@ -154,7 +132,7 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus url={uploadUrl} accept={accept} onUploadStart={() => setShowLoader(true)} - onUploadComplete={handleUploadComplete} + onUploadComplete={update} /> )} @@ -169,9 +147,9 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus pagination={{ ...pagination, showSizeChanger: false, - onChange: (page) => setPage(page), + onChange: setPage, }} - onRowDelete={hasPermission(`File.edit${idCategory}`) && handleFileDelete} + onRowDelete={handleFileDelete} rowKey={(record) => record.id} tableName={tableName ?? `file_${idCategory}`} /> diff --git a/src/pages/Documents/index.jsx b/src/pages/Documents/index.jsx index 1d79c0e..5452d63 100644 --- a/src/pages/Documents/index.jsx +++ b/src/pages/Documents/index.jsx @@ -1,5 +1,5 @@ import { join } from 'path' -import { memo } from 'react' +import { memo, useMemo } from 'react' import { Layout, Menu } from 'antd' import { FolderOutlined } from '@ant-design/icons' import { Switch, useParams } from 'react-router-dom' @@ -25,7 +25,7 @@ export const documentCategories = [ export const MenuDocuments = memo(({ idWell }) => { const { category } = useParams() - const root = `/well/${idWell}/document` + const root = useMemo(() => `/well/${idWell}/document`, [idWell]) return ( <> diff --git a/src/pages/DrillingProgram/CategoryEditor.jsx b/src/pages/DrillingProgram/CategoryEditor.jsx index 15300a5..a9fedec 100644 --- 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, useState } from 'react' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' import { BehaviorSubject, debounceTime, distinctUntilChanged, filter, map } from 'rxjs' import { UserView } from '@components/views' @@ -113,7 +113,7 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => `Изменение статуса пользователя` ), [users, idWell, category.idFileCategory]) - const userColumns = [ + const userColumns = useMemo(() => [ makeColumn('Пользователь', 'user', { sorter: (a, b) => (a?.user?.surname && b?.user?.surname) ? a.user.surname.localeCompare(b.user.surname) : 0, render: (user) => , @@ -129,7 +129,7 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => /> ), }) - ] + ], [changeUserStatus]) const onSearchTextChange = useCallback((e) => subject?.next(e?.target?.value), [subject]) diff --git a/src/pages/DrillingProgram/CategoryRender.jsx b/src/pages/DrillingProgram/CategoryRender.jsx index 7a00050..3213c07 100644 --- a/src/pages/DrillingProgram/CategoryRender.jsx +++ b/src/pages/DrillingProgram/CategoryRender.jsx @@ -1,4 +1,4 @@ -import { memo, useCallback, useState } from 'react' +import { memo, useCallback, useMemo, useState } from 'react' import { Button, Input, Popconfirm, Form } from 'antd' import { DeleteOutlined, @@ -44,7 +44,7 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist file // Информация о файле } = partData ?? {} - const uploadUrl = `/api/well/${idWell}/drillingProgram/part/${idFileCategory}` + const uploadUrl = useMemo(() => `/api/well/${idWell}/drillingProgram/part/${idFileCategory}`, [idWell, idFileCategory]) const [isUploading, setIsUploading] = useState(false) const [isDeleting, setIsDeleting] = useState(false) diff --git a/src/pages/DrillingProgram/index.jsx b/src/pages/DrillingProgram/index.jsx index 2e78b81..303d240 100644 --- 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, useState } from 'react' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' import LoaderPortal from '@components/LoaderPortal' import { downloadFile, formatBytes, invokeWebApiWrapperAsync } from '@components/factory' @@ -52,11 +52,11 @@ export const DrillingProgram = memo(({ idWell }) => { parts, program, error, - } = data + } = useMemo(() => data, [data]) - const stateId = idState ?? idStateUnknown - const state = stateString[stateId] - const StateIcon = state.icon + const stateId = useMemo(() => idState ?? idStateUnknown, [idState]) + const state = useMemo(() => stateString[stateId], [stateId]) + const StateIcon = useMemo(() => state.icon, [state?.icon]) const updateData = useCallback(async () => await invokeWebApiWrapperAsync( async () => { @@ -76,15 +76,15 @@ export const DrillingProgram = memo(({ idWell }) => { useEffect(() => updateData(), [updateData]) - const onCategoryEdit = (catId) => { + const onCategoryEdit = useCallback((catId) => { setSelectedCategory(catId) setEditorVisible(!!catId) - } + }, []) - const onCategoryHistory = (catId) => { + const onCategoryHistory = useCallback((catId) => { setSelectedCategory(catId) setHistoryVisible(!!catId) - } + }, []) const onEditorClosed = useCallback(() => { setEditorVisible(false) diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 9015588..ff53576 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -13,9 +13,10 @@ import '@styles/index.css' import Logo from '@images/Logo' export const Login = memo(() => { + const [showLoader, setShowLoader] = useState(false) + const history = useHistory() const location = useLocation() - const [showLoader, setShowLoader] = useState(false) const handleLogin = useCallback((formData) => invokeWebApiWrapperAsync( async () => { diff --git a/src/pages/Measure/InclinometryTable.jsx b/src/pages/Measure/InclinometryTable.jsx index 7772cfc..18d1660 100644 --- a/src/pages/Measure/InclinometryTable.jsx +++ b/src/pages/Measure/InclinometryTable.jsx @@ -1,5 +1,5 @@ import { Modal } from 'antd' -import { memo, useEffect, useState } from 'react' +import { memo, useMemo } from 'react' import { Table } from '@components/Table' import { formatDate } from '@utils' @@ -18,21 +18,18 @@ const dateColumn = { } export const InclinometryTable = memo(({ group, visible, onClose }) => { - const [tableColumns, setTableColumns] = useState([]) - const [tableData, setTableData] = useState([]) - - useEffect(() => setTableColumns([ + const tableColumns = useMemo(() => [ dateColumn, ...(group?.columns?.map((column) => ({ ...column, title: v(column.title) })) ?? []) - ]), [group?.columns]) + ], [group?.columns]) - useEffect(() => setTableData(group?.values?.map(row => ({ + const tableData = useMemo(() => group?.values?.map(row => ({ date: row.timestamp, ...row.data - }))), [group?.values]) + })), [group?.values]) return !group?.columns ? null : ( cols.map(col => ({ render: renderDelegate, ...col })) +const disabled = !hasPermission('Measure.edit') + export const MeasureTable = memo(({ idWell, 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 [data, setData] = useState([]) const [measuresForm] = Form.useForm() - useEffect(() => { - let data = [group.defaultValue] - if (group?.values?.length > 0) - data = group.values - setData(data) - setDisplayedValues(data.at(-1)) - }, [group.defaultValue, group.values]) + const data = useMemo(() => group?.values?.length > 0 ? group.values : [group?.defaultValue], [group?.defaultValue, group?.values]) + + useEffect(() => setDisplayedValues(data.at(-1)), [data]) useEffect(() => { const switchableColumns = createEditingColumns( @@ -64,17 +61,15 @@ export const MeasureTable = memo(({ idWell, group, updateMeasuresFunc, additiona `Не удалось удалить запись ${displayedValues.id} для скважины "${idWell}"`, 'Удаление записи для скважины' ) + const editingDisabled = useMemo(() => disabled || !!displayedValues?.isDefaultData, [displayedValues?.isDefaultData]) + const deleteDisabled = useMemo(() => !hasPermission('Measure.delete') || !!displayedValues?.isDefaultData, [displayedValues?.isDefaultData]) - const disabled = !hasPermission('Measure.edit') - const editingDisabled = disabled || !!displayedValues?.isDefaultData - const deleteDisabled = !hasPermission('Measure.delete') || !!displayedValues?.isDefaultData - - const editTable = (action) => { + const editTable = useCallback((action) => { setEditingActionName(action) setIsTableEditing(true) - } + }, []) - const handleSubmitMeasuresForm = async (formData) => await invokeWebApiWrapperAsync( + const handleSubmitMeasuresForm = useCallback(async (formData) => await invokeWebApiWrapperAsync( async () => { measuresForm.validateFields() @@ -99,7 +94,7 @@ export const MeasureTable = memo(({ idWell, group, updateMeasuresFunc, additiona setShowLoader, `Не удалось добавить/изменить запись для скаважины "${idWell}"`, 'Добавление/изменение записи по скважине' - ) + ), [displayedValues?.id, displayedValues?.timestamp, editingActionName, group.idCategory, idWell, measuresForm, updateMeasuresFunc]) return ( <> diff --git a/src/pages/Messages.jsx b/src/pages/Messages.jsx index e4bd773..2500ada 100644 --- a/src/pages/Messages.jsx +++ b/src/pages/Messages.jsx @@ -1,5 +1,5 @@ import moment from 'moment' -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useCallback } from 'react' import { Table, Select, DatePicker, Input } from 'antd' import { MessageService } from '@api' @@ -65,6 +65,8 @@ const filterOptions = [ { value: 3, label: 'Информация' }, ] +const children = filterOptions.map((line) => ) + // Данные для таблицы export const Messages = memo(({ idWell }) => { const [messages, setMessages] = useState([]) @@ -75,9 +77,7 @@ export const Messages = memo(({ idWell }) => { const [searchString, setSearchString] = useState('') const [showLoader, setShowLoader] = useState(false) - const children = filterOptions.map((line) => ) - - const onChangeSearchString = (message) => setSearchString(message.length > 2 ? message : '') + const onChangeSearchString = useCallback((message) => setSearchString(message.length > 2 ? message : ''), []) useEffect(() => invokeWebApiWrapperAsync( async () => { diff --git a/src/pages/Report/index.jsx b/src/pages/Report/index.jsx index 3fb7917..ce8a0d4 100644 --- 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 } from 'react' +import { useState, useEffect, memo, useCallback } from 'react' import { Radio, Button, Select, notification } from 'antd' import { ReportService } from '@api' @@ -43,7 +43,7 @@ export const Report = memo(({ idWell }) => { const [pagesCount, setPagesCount] = useState(0) const [showLoader, setShowLoader] = useState(false) - const handleReportCreation = async () => await invokeWebApiWrapperAsync( + const handleReportCreation = useCallback(async () => await invokeWebApiWrapperAsync( async () => { const taskId = await ReportService.createReport( idWell, @@ -81,9 +81,11 @@ export const Report = memo(({ idWell }) => { ${filterDateRange[0].format(dateTimeFormat)} по ${filterDateRange[1].format(dateTimeFormat)}`, 'Создание отчёта по скважине' - ) + ), [filterDateRange, format, idWell, step]) - const disabledDate = (current) => !current.isBetween(aviableDateRange[0], aviableDateRange[1], 'seconds', '[]') + const disabledDate = useCallback((current) => + !current.isBetween(aviableDateRange[0], aviableDateRange[1], 'seconds', '[]') + , [aviableDateRange]) useEffect(() => invokeWebApiWrapperAsync( async () => { diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index fe1e40b..5df9768 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -1,4 +1,4 @@ -import { memo } from 'react' +import { memo, useMemo } from 'react' import { FolderOutlined, FundViewOutlined, @@ -30,7 +30,7 @@ const { Content } = Layout export const Well = memo(() => { const { idWell, tab } = useParams() - const rootPath = `/well/${idWell}` + const rootPath = useMemo(() => `/well/${idWell}`, [idWell]) return ( diff --git a/src/pages/WellOperations/WellDrillParams.jsx b/src/pages/WellOperations/WellDrillParams.jsx index 87c8407..8db51b6 100644 --- a/src/pages/WellOperations/WellDrillParams.jsx +++ b/src/pages/WellOperations/WellDrillParams.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, memo } from 'react' +import { useState, useEffect, useCallback, memo, useMemo } from 'react' import { EditableTable, @@ -54,15 +54,15 @@ export const WellDrillParams = memo(({ idWell }) => { await updateParams() })(), [idWell, updateParams]) - const handlerProps = { + const handlerProps = useMemo(() => ({ service: DrillParamsService, setLoader: setShowLoader, errorMsg: `Не удалось выполнить операцию`, onComplete: updateParams, idWell - } + }), [idWell, updateParams]) - const recordParser = (record) => ({ ...record, idWell }) + const recordParser = useCallback((record) => ({ ...record, idWell }), [idWell]) return ( diff --git a/src/pages/WellOperations/WellOperationsEditor.jsx b/src/pages/WellOperations/WellOperationsEditor.jsx index 7aebbea..9ea77c4 100644 --- a/src/pages/WellOperations/WellOperationsEditor.jsx +++ b/src/pages/WellOperations/WellOperationsEditor.jsx @@ -135,13 +135,13 @@ export const WellOperationsEditor = memo(({ idWell, idType, showNpt, ...other }) useEffect(updateOperations, [updateOperations]) - const handlerProps = { + const handlerProps = useMemo(() => ({ service: WellOperationService, setLoader: setShowLoader, errorMsg: `Не удалось выполнить операцию`, onComplete: updateOperations, idWell - } + }), [idWell, updateOperations]) const onRow = useCallback((record) => { if (selectedIds?.includes(record.id))