diff --git a/package.json b/package.json index c04d2a3..9d7fbc1 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "react_test": "react-scripts test", "eject": "react-scripts eject" }, - "proxy": "http://46.146.209.148:89/", + "proxy": "http://46.146.209.148:89", "eslintConfig": { "extends": [ "react-app", diff --git a/src/pages/AdminPanel/UserController/index.jsx b/src/pages/AdminPanel/UserController/index.jsx index 803c427..d6b9177 100644 --- a/src/pages/AdminPanel/UserController/index.jsx +++ b/src/pages/AdminPanel/UserController/index.jsx @@ -17,7 +17,7 @@ import { ChangePassword } from '@components/ChangePassword' import { invokeWebApiWrapperAsync } from '@components/factory' import { AdminCompanyService, AdminUserRoleService, AdminUserService } from '@api' import { createLoginRules, nameRules, phoneRules, emailRules } from '@utils/validationRules' -import { makeTextOnFilter, makeTextFilters } from '@utils/table' +import { makeTextOnFilter, makeTextFilters, makeObjectOnFilter, makeArrayOnFilter } from '@utils/table' import { hasPermission } from '@utils/permissions' import { arrayOrDefault } from '@utils' @@ -61,7 +61,7 @@ export const UserController = () => { setUsers(users) const filters = makeTextFilters(users, ['surname', 'name', 'patronymic', 'email']) - + const roleFilters = [{ text: 'Без роли', value: null }, ...roles.map((role) => ({ text: role.caption, value: role.caption }))] setColumns([ makeColumn('Логин', 'login', { @@ -124,6 +124,8 @@ export const UserController = () => { makeColumn('Роли', 'roleNames', { editable: true, input: , + filters: roleFilters, + onFilter: makeArrayOnFilter('roleNames'), render: (item) => item?.map((elm) => ( role.caption === elm)} /> diff --git a/src/pages/Cluster/ClusterWells.jsx b/src/pages/Cluster/ClusterWells.jsx index 488a48d..4fa191a 100644 --- a/src/pages/Cluster/ClusterWells.jsx +++ b/src/pages/Cluster/ClusterWells.jsx @@ -16,13 +16,14 @@ import { CompanyView } from '@components/views' import LoaderPortal from '@components/LoaderPortal' import PointerIcon from '@components/icons/PointerIcon' import { invokeWebApiWrapperAsync } from '@components/factory' - -import { Tvd } from '@pages/WellOperations/Tvd' import { getOperations, calcAndUpdateStatsBySections, makeFilterMinMaxFunction -} from './functions' +} from '@utils/functions' +import { isRawDate } from '@utils' + +import { Tvd } from '@pages/WellOperations/Tvd' import WellOperationsTable from './WellOperationsTable' const filtersMinMax = [ @@ -61,14 +62,11 @@ export const ClusterWells = ({ statsWells }) => { useEffect(() => { let data = statsWells?.map((well) => { if (!filtersWellsType.some((el) => el.text === well.wellType)) - filtersWellsType.push({ text: well.wellType, value: well.wellType,}) + filtersWellsType.push({ text: well.wellType, value: well.wellType }) - let periodPlanValue = well.total?.plan?.start && well.total?.plan?.end - ? (new Date(well.total?.plan?.end) - new Date(well.total?.plan?.start)) / DAY_IN_MS - : '-' - let periodFactValue = well.total?.fact?.start && well.total?.fact?.end - ? (new Date(well.total?.fact?.end) - new Date(well.total?.fact?.start)) / DAY_IN_MS - : '-' + const dateOrM = (a, b) => a && b ? (new Date(b) - new Date(a)) / DAY_IN_MS : '-' + const periodPlanValue = dateOrM(well.total?.plan?.start, well.total?.plan?.end) + const periodFactValue = dateOrM(well.total?.fact?.start, well.total?.fact?.end) return { key: well.caption, @@ -106,9 +104,7 @@ export const ClusterWells = ({ statsWells }) => { setTableData(data) }, [statsWells]) - const getDate = (str) => Number.isNaN(+new Date(str)) || +new Date(str) === 0 - ? '-' - : new Date(str).toLocaleString() + const getDate = (str) => isRawDate(str) ? new Date(str).toLocaleString() : '-' const columns = [ makeTextColumn('скв №', 'caption', null, null, diff --git a/src/pages/Cluster/WellOperationsTable.jsx b/src/pages/Cluster/WellOperationsTable.jsx index 85f24a8..5731d56 100644 --- a/src/pages/Cluster/WellOperationsTable.jsx +++ b/src/pages/Cluster/WellOperationsTable.jsx @@ -1,9 +1,8 @@ - import { Table } from 'antd' import { makeTextColumn, makeNumericColumnPlanFact } from '@components/Table' -import { getPrecision } from './functions' +import { getPrecision } from '@utils/functions' export const WellOperationsTable = ({ wellOperations }) => { const columns = [ @@ -27,7 +26,7 @@ export const WellOperationsTable = ({ wellOperations }) => { commentFact: el.fact?.comment ?? '-' })) - return( + return ( Number.isFinite(number) ? number.toFixed(2) : '-' - -export const getOperations = async (idWell) => { - const ops = await OperationStatService.getTvd(idWell) - - if (!ops) return [] - - const convert = wellOperationDto => ({ - key: wellOperationDto?.id, - depth: wellOperationDto?.depthStart, - date: wellOperationDto?.dateStart, - day: wellOperationDto?.day, - }) - - const planData = ops - .map(item => convert(item.plan)) - .filter(el => el.key) - - const factData = ops - .map(item => convert(item.fact)) - .filter(el => el.key) - - const predictData = ops - .map(item => convert(item.predict)) - .filter(el => el.key) - - return { operations: ops, plan: planData, fact: factData, predict: predictData } -} - -export const makeFilterMinMaxFunction = (key) => (filterValue, - dataItem) => - filterValue === 'max' - ? dataItem[maxPrefix + key] - : filterValue === 'min' - ? dataItem[minPrefix + key] - : false - -export const calcAndUpdateStats = (data, keys) => { - const mins = {} - const maxs = {} - - keys.forEach((key) => { - maxs[key] = Number.MIN_VALUE - mins[key] = Number.MAX_VALUE - }) - - data.forEach((item) => { - keys.forEach((key) => { - if (mins[key] > item[key]) mins[key] = item[key] - if (maxs[key] < item[key]) maxs[key] = item[key] - }) - }) - - for (let i = 0; i < data.length; i++) { - keys.forEach((key) => { - data[i][maxPrefix + key] = data[i][key] === maxs[key] - data[i][minPrefix + key] = data[i][key] === mins[key] - }) - } -} - -export const calcAndUpdateStatsBySections = (data, keys) => { - const sectionTypes = new Set() - data.forEach((item) => sectionTypes.add(item.sectionType)) - sectionTypes.forEach(sectionType => { - const filteredBySectionData = data.filter((item) => item.sectionType === sectionType) - calcAndUpdateStats(filteredBySectionData, keys) - }) -} diff --git a/src/pages/Measure/MeasureTable.jsx b/src/pages/Measure/MeasureTable.jsx index 2cdf50a..af0be5d 100644 --- a/src/pages/Measure/MeasureTable.jsx +++ b/src/pages/Measure/MeasureTable.jsx @@ -138,20 +138,20 @@ export const MeasureTable = memo(({ idWell, group, updateMeasuresFunc, additiona
- {data.map((item, index) => + {data.map((item, index) => ( setDisplayedValues(item)} - dot={item?.id === displayedValues?.id && + dot={item?.id === displayedValues?.id && ( - } + )} > - {formatDate(item.timestamp, true) ?? 'Нет данных'} + {formatDate(item.timestamp) ?? 'Нет данных'} - )} + ))}
diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 1885889..c16b00c 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -6,7 +6,6 @@ import { FilePdfOutlined, DatabaseOutlined, ExperimentOutlined, - FundProjectionScreenOutlined, } from '@ant-design/icons' import { Layout, Menu } from 'antd' import { Switch, useParams } from 'react-router-dom' diff --git a/src/pages/WellOperations/Tvd.jsx b/src/pages/WellOperations/Tvd.jsx index e58743c..0f6f5e4 100644 --- a/src/pages/WellOperations/Tvd.jsx +++ b/src/pages/WellOperations/Tvd.jsx @@ -16,8 +16,7 @@ import ChartDataLabels from 'chartjs-plugin-datalabels' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' - -import { getOperations } from '@pages/Cluster/functions' +import { getOperations } from '@utils/functions' Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement, Legend, ChartDataLabels, zoomPlugin) diff --git a/src/pages/WellOperations/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/WellOperations/WellCompositeEditor/WellCompositeSections.jsx index cc08b2d..44927da 100644 --- a/src/pages/WellOperations/WellCompositeEditor/WellCompositeSections.jsx +++ b/src/pages/WellOperations/WellCompositeEditor/WellCompositeSections.jsx @@ -14,7 +14,7 @@ import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction, getOperations -} from '@pages/Cluster/functions' +} from '@utils/functions' import WellOperationsTable from '@pages/Cluster/WellOperationsTable' import { Tvd } from '../Tvd' import { getColumns } from '../WellDrillParams' diff --git a/src/utils/functions.tsx b/src/utils/functions.tsx new file mode 100644 index 0000000..453eb07 --- /dev/null +++ b/src/utils/functions.tsx @@ -0,0 +1,86 @@ +import { OperationStatService, WellOperationDto, WellOperationDtoPlanFactPredictBase } from '@api' + +const maxPrefix = 'isMax' +const minPrefix = 'isMin' + +export const getPrecision = (number: number) => Number.isFinite(number) ? number.toFixed(2) : '-' + +export type KeyType = number | string + +export type SaubData = { + key?: number + depth?: number + date?: string + day?: number +} + +export const getOperations = async (idWell: number): Promise<{ + operations?: WellOperationDtoPlanFactPredictBase[], + plan?: SaubData[] + fact?: SaubData[] + predict?: SaubData[] +}> => { + const ops = await OperationStatService.getTvd(idWell) + + if (!ops) return {} + + const convert = (operation?: WellOperationDto): SaubData => ({ + key: operation?.id, + depth: operation?.depthStart, + date: operation?.dateStart, + day: operation?.day, + }) + + const planData = ops + .map(item => convert(item.plan)) + .filter(el => el.key) + + const factData = ops + .map(item => convert(item.fact)) + .filter(el => el.key) + + const predictData = ops + .map(item => convert(item.predict)) + .filter(el => el.key) + + return { operations: ops, plan: planData, fact: factData, predict: predictData } +} + +export const makeFilterMinMaxFunction = (key: KeyType) => (filterValue: string, dataItem: Record) => { + if (filterValue === 'max') return dataItem[maxPrefix + key] + if (filterValue === 'min') return dataItem[minPrefix + key] + return false +} + +export const calcAndUpdateStats = (data: Record[], keys: KeyType[]) => { + const mins: Record = {} + const maxs: Record = {} + + keys.forEach((key) => { + maxs[key] = Number.MIN_VALUE + mins[key] = Number.MAX_VALUE + }) + + data.forEach((item) => { + keys.forEach((key) => { + if (mins[key] > item[key]) mins[key] = item[key] + if (maxs[key] < item[key]) maxs[key] = item[key] + }) + }) + + for (let i = 0; i < data.length; i++) { + keys.forEach((key) => { + data[i][maxPrefix + key] = data[i][key] === maxs[key] + data[i][minPrefix + key] = data[i][key] === mins[key] + }) + } +} + +export const calcAndUpdateStatsBySections = (data: { sectionType: any }[], keys: KeyType[]) => { + const sectionTypes = new Set() + data.forEach((item) => sectionTypes.add(item.sectionType)) + sectionTypes.forEach(sectionType => { + const filteredBySectionData = data.filter((item) => item.sectionType === sectionType) + calcAndUpdateStats(filteredBySectionData, keys) + }) +} diff --git a/src/utils/table.ts b/src/utils/table.ts index 12ff435..dcf0e2d 100644 --- a/src/utils/table.ts +++ b/src/utils/table.ts @@ -1,5 +1,11 @@ export const makeTextOnFilter = (key: string) => - (value: string, record?: Record) => record?.[key]?.startsWith(value) + (value: string, record?: Record) => String(record?.[key]).startsWith(value) + +export const makeArrayOnFilter = (key: string) => + (value: string, record?: Record) => (!value && (record?.[key]?.length ?? 0) <= 0) || record?.[key]?.includes(value) + +export const makeObjectOnFilter = (field: string, key: string) => + (value: string, record?: Record>) => String(record?.[field]?.[key]).startsWith(value) export const makeTextFilters = (array: Record[], keys: string[]) => { const filters: string[][] = Array(keys.length)