forked from ddrilling/asb_cloud_front
Merge branch 'dev' into fix/file-download-page-fix
# Conflicts: # src/pages/FileDownload.jsx
This commit is contained in:
commit
a4db41fdd4
@ -12,8 +12,7 @@
|
||||
"react-dom": "^18.1.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"rxjs": "^7.5.5",
|
||||
"usehooks-ts": "^2.6.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
"usehooks-ts": "^2.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
|
165
src/components/FastRunMenu.tsx
Normal file
165
src/components/FastRunMenu.tsx
Normal file
@ -0,0 +1,165 @@
|
||||
import { memo, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { BaseSelectRef } from 'rc-select'
|
||||
import { AutoComplete } from 'antd'
|
||||
import { join } from 'path'
|
||||
|
||||
import { useWell } from '@asb/context'
|
||||
import { makeItem, PrivateWellMenuItem } from './PrivateWellMenu'
|
||||
import { hasPermission, isURLAvailable } from '@utils'
|
||||
|
||||
import { menuItems as adminMenuItems } from '@pages/AdminPanel/AdminNavigationMenu'
|
||||
import { menuItems as wellMenuItems } from '@pages/Well/NavigationMenu'
|
||||
|
||||
import '@styles/fast_run_menu.less'
|
||||
|
||||
const transliterationTable = {
|
||||
'q': 'й', 'w': 'ц', 'e': 'у', 'r': 'к', 't': 'е', 'y': 'н', 'u': 'г', 'i': 'ш', 'o': 'щ', 'p': 'з', '[': 'х', ']': 'ъ', '{': 'х', '}': 'ъ',
|
||||
'a': 'ф', 's': 'ы', 'd': 'в', 'f': 'а', 'g': 'п', 'h': 'р', 'j': 'о', 'k': 'л', 'l': 'д', ';': 'ж', "'": 'э', ':': 'ж', '"': 'э',
|
||||
'z': 'я', 'x': 'ч', 'c': 'с', 'v': 'м', 'b': 'и', 'n': 'т', 'm': 'ь', ',': 'б', '.': 'ю', '<': 'б', '>': 'ю',
|
||||
}
|
||||
|
||||
type OptionType = {
|
||||
value: string
|
||||
label: ReactNode
|
||||
}
|
||||
|
||||
const transliterateToRu = (text: string) => Object.entries(transliterationTable).reduce((out, [en, ru]) => out.replaceAll(en, ru), text.toLowerCase())
|
||||
const transliterateToEn = (text: string) => Object.entries(transliterationTable).reduce((out, [en, ru]) => out.replaceAll(ru, en), text.toLowerCase())
|
||||
const applyVars = (route: string, vars?: object): string => !vars ? route :
|
||||
Object.entries(vars).reduce((out, [key, value]) => out.replaceAll(`{${key}}`, value), route)
|
||||
|
||||
const makeOptions = (items: PrivateWellMenuItem[], vars?: object): OptionType[] => {
|
||||
const out: OptionType[] = []
|
||||
items.forEach((item) => {
|
||||
if (!hasPermission(item.permissions)) return
|
||||
out.push({
|
||||
label: item.title,
|
||||
value: applyVars(item.route, vars),
|
||||
})
|
||||
if (item.children) {
|
||||
const childrenOptions = makeOptions(item.children).map((child) => ({
|
||||
label: `${item.title} > ${child.label}`,
|
||||
value: applyVars(join(item.route, String(child.value)), vars),
|
||||
}))
|
||||
out.push(...childrenOptions)
|
||||
}
|
||||
})
|
||||
return out
|
||||
}
|
||||
|
||||
const makeFindInString = (text: string) => {
|
||||
const searchText = text.toLowerCase()
|
||||
const toRu = transliterateToRu(searchText)
|
||||
const toEn = transliterateToEn(searchText)
|
||||
|
||||
return (sourceText: string) => {
|
||||
const text = sourceText.toLowerCase()
|
||||
let idx = text.indexOf(searchText)
|
||||
if (idx < 0 && (idx = text.indexOf(toRu)) < 0 && (idx = text.indexOf(toEn)) < 0) return false
|
||||
return { from: idx, to: idx + searchText.length }
|
||||
}
|
||||
}
|
||||
|
||||
export const FastRunMenu = memo(() => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [value, setValue] = useState<string | null>()
|
||||
const [results, setResults] = useState<OptionType[]>([])
|
||||
const ref = useRef<BaseSelectRef | null>(null)
|
||||
|
||||
const [well] = useWell()
|
||||
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
|
||||
const options = useMemo(() => {
|
||||
const menus = [
|
||||
makeItem('Месторождения', '/deposit', []),
|
||||
]
|
||||
|
||||
if (isURLAvailable('/admin'))
|
||||
menus.push(makeItem('Панель администратора', '/admin', [], undefined, adminMenuItems as PrivateWellMenuItem[]))
|
||||
|
||||
if (well.id)
|
||||
menus.push(
|
||||
makeItem(`Куст (${well.cluster})`, `/cluster/${well.idCluster}`, []),
|
||||
makeItem(`Скважина (${well.caption})`, '/well/{idWell}', [], undefined, wellMenuItems),
|
||||
)
|
||||
|
||||
return makeOptions(menus, { idWell: well.id })
|
||||
}, [well])
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
setIsOpen(false)
|
||||
setValue(null)
|
||||
}, [])
|
||||
|
||||
const onTextChanged = useCallback((value: any) => {
|
||||
navigate(value, { state: { from: location.pathname } })
|
||||
onClose()
|
||||
}, [onClose])
|
||||
|
||||
const onSearch = useCallback((text: string) => {
|
||||
if (text.trim() === '') {
|
||||
setResults(options)
|
||||
return
|
||||
}
|
||||
const findInString = makeFindInString(text)
|
||||
const results = options.map((option) => {
|
||||
const label = String(option.label)
|
||||
const idx = findInString(label.toLowerCase())
|
||||
if (!idx) return findInString(option.value.toLowerCase()) ? option : false
|
||||
|
||||
return {
|
||||
...option,
|
||||
label: <>
|
||||
{label.slice(0, idx.from)}
|
||||
<span className={'fast-run-menu-text-found'}>
|
||||
{label.slice(idx.from, idx.to)}
|
||||
</span>
|
||||
{label.slice(idx.to)}
|
||||
</>
|
||||
}
|
||||
}).filter(Boolean) as OptionType[]
|
||||
|
||||
setResults(results)
|
||||
}, [options])
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (event: KeyboardEvent) => {
|
||||
if (event.altKey && event.code === 'KeyA')
|
||||
setIsOpen((prev) => !prev)
|
||||
}
|
||||
|
||||
document.addEventListener('keyup', listener)
|
||||
|
||||
return () => document.removeEventListener('keyup', listener)
|
||||
}, [ref.current])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return
|
||||
ref.current?.focus()
|
||||
ref.current?.scrollTo(0)
|
||||
}, [isOpen])
|
||||
|
||||
useEffect(() => onSearch(''), [onSearch])
|
||||
|
||||
return isOpen ? (
|
||||
<div className={'fast-run-menu'}>
|
||||
<AutoComplete
|
||||
ref={ref}
|
||||
autoFocus
|
||||
style={{ width: '100%' }}
|
||||
options={results}
|
||||
onBlur={onClose}
|
||||
onChange={setValue}
|
||||
onSearch={onSearch}
|
||||
placeholder={'Введите название страницы...'}
|
||||
onSelect={onTextChanged}
|
||||
value={value}
|
||||
/>
|
||||
</div>
|
||||
) : <></>
|
||||
})
|
||||
|
||||
export default FastRunMenu
|
@ -12,7 +12,7 @@ import {
|
||||
import { LayoutPropsContext } from '@asb/context'
|
||||
import { UserMenu, UserMenuProps } from '@components/UserMenu'
|
||||
import { WellTreeSelector, WellTreeSelectorProps } from '@components/selectors/WellTreeSelector'
|
||||
import { isURLAvailable, wrapPrivateComponent } from '@utils'
|
||||
import { isURLAvailable, withPermissions } from '@utils'
|
||||
|
||||
import SuspenseFallback from './SuspenseFallback'
|
||||
|
||||
@ -114,7 +114,7 @@ const _LayoutPortal = memo(() => {
|
||||
<a style={{ userSelect: 'none' }} onClick={() => setWellsTreeOpen((prev) => !prev)}>{currentWell}</a>
|
||||
</Breadcrumb.Item>
|
||||
)}
|
||||
{breadcrumb}
|
||||
{breadcrumb !== true && breadcrumb}
|
||||
</Breadcrumb>
|
||||
)}
|
||||
{topRightBlock}
|
||||
@ -131,6 +131,6 @@ const _LayoutPortal = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export const LayoutPortal = wrapPrivateComponent(_LayoutPortal, { requirements: ['Deposit.get'] })
|
||||
export const LayoutPortal = withPermissions(_LayoutPortal, ['Deposit.get'])
|
||||
|
||||
export default LayoutPortal
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Breadcrumb, BreadcrumbItemProps } from 'antd'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { memo, useMemo } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { join } from 'path'
|
||||
|
||||
import { PrivateWellMenuItem } from '@components/PrivateWellMenu'
|
||||
import { FunctionalValue, useFunctionalValue } from '@utils'
|
||||
import { FunctionalValue, getFunctionalValue, } from '@utils'
|
||||
|
||||
export const makeBreadcrumbItems = (items: PrivateWellMenuItem[], pathParts: string[], root: string = '/') => {
|
||||
const out = []
|
||||
@ -22,35 +21,26 @@ export const makeBreadcrumbItems = (items: PrivateWellMenuItem[], pathParts: str
|
||||
return out
|
||||
}
|
||||
|
||||
export type MenuBreadcrumbItemsProps = {
|
||||
menuItems: PrivateWellMenuItem[]
|
||||
pathRoot?: RegExp
|
||||
itemsProps?: FunctionalValue<(item: PrivateWellMenuItem) => BreadcrumbItemProps>
|
||||
itemRender?: (item: PrivateWellMenuItem) => JSX.Element
|
||||
export const makeMenuBreadcrumbItems = (
|
||||
menuItems: PrivateWellMenuItem[],
|
||||
path: string,
|
||||
pathRoot: RegExp = /^\//,
|
||||
itemsProps?: FunctionalValue<(item: PrivateWellMenuItem) => BreadcrumbItemProps>,
|
||||
itemRender?: (item: PrivateWellMenuItem) => JSX.Element,
|
||||
) => {
|
||||
const getItemProps = getFunctionalValue(itemsProps)
|
||||
|
||||
const rootPart = pathRoot.exec(path)
|
||||
if (!rootPart || rootPart.length <= 0) return []
|
||||
const root = rootPart[0]
|
||||
const parts = path.trim().slice(root.length).split('/')
|
||||
const items = makeBreadcrumbItems(menuItems, parts, root)
|
||||
|
||||
return items.map((item) => (
|
||||
<Breadcrumb.Item key={item.route} {...getItemProps(item)}>
|
||||
{itemRender ? itemRender(item) : (
|
||||
<Link to={item.route}>{item.title}</Link>
|
||||
)}
|
||||
</Breadcrumb.Item>
|
||||
))
|
||||
}
|
||||
|
||||
export const MenuBreadcrumbItems = memo<MenuBreadcrumbItemsProps>(({ menuItems, pathRoot = /^\//, itemsProps, itemRender }) => {
|
||||
const location = useLocation()
|
||||
const getItemProps = useFunctionalValue(itemsProps)
|
||||
|
||||
const items = useMemo(() => {
|
||||
const path = location.pathname
|
||||
const rootPart = pathRoot.exec(path)
|
||||
if (!rootPart || rootPart.length <= 0) return []
|
||||
const root = rootPart[0]
|
||||
const parts = path.trim().slice(root.length).split('/')
|
||||
return makeBreadcrumbItems(menuItems, parts, root)
|
||||
}, [location, menuItems, pathRoot])
|
||||
|
||||
return (
|
||||
<>
|
||||
{items.map((item) => (
|
||||
<Breadcrumb.Item key={item.route} {...getItemProps(item)}>
|
||||
{itemRender ? itemRender(item) : (
|
||||
<Link to={item.route}>{item.title}</Link>
|
||||
)}
|
||||
</Breadcrumb.Item>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
@ -2,29 +2,14 @@ import { ReactNode } from 'react'
|
||||
import { Rule } from 'antd/lib/form'
|
||||
import { ColumnProps } from 'antd/lib/table'
|
||||
|
||||
export { makeDateColumn } from './date'
|
||||
export { makeTimeColumn } from './time'
|
||||
export {
|
||||
RegExpIsFloat,
|
||||
makeNumericRender,
|
||||
makeNumericColumn,
|
||||
makeNumericColumnOptions,
|
||||
makeNumericColumnPlanFact,
|
||||
makeNumericStartEnd,
|
||||
makeNumericMinMax,
|
||||
} from './numeric'
|
||||
export { makeColumnsPlanFact } from './plan_fact'
|
||||
export { makeSelectColumn } from './select'
|
||||
export { makeTagColumn, makeTagInput } from './tag'
|
||||
export { makeFilterTextMatch, makeTextColumn } from './text'
|
||||
export {
|
||||
timezoneOptions,
|
||||
TimezoneSelect,
|
||||
makeTimezoneColumn,
|
||||
makeTimezoneRenderer
|
||||
} from './timezone'
|
||||
|
||||
export type { TagInputProps } from './tag'
|
||||
export * from './date'
|
||||
export * from './time'
|
||||
export * from './numeric'
|
||||
export * from './plan_fact'
|
||||
export * from './select'
|
||||
export * from './tag'
|
||||
export * from './text'
|
||||
export * from './timezone'
|
||||
|
||||
export type DataType<T = any> = Record<string, T>
|
||||
export type RenderMethod<T = any> = (value: T, dataset?: DataType<T>, index?: number) => ReactNode
|
||||
|
@ -1,58 +1,24 @@
|
||||
export { makeDateSorter, makeNumericSorter, makeStringSorter, makeTimeSorter } from './sorters'
|
||||
export { EditableTable, makeTableAction } from './EditableTable'
|
||||
export { DatePickerWrapper } from './DatePickerWrapper'
|
||||
export { TimePickerWrapper } from './TimePickerWrapper'
|
||||
export { DateRangeWrapper } from './DateRangeWrapper'
|
||||
export { Table } from './Table'
|
||||
export {
|
||||
RegExpIsFloat,
|
||||
timezoneOptions,
|
||||
TimezoneSelect,
|
||||
makeDateColumn,
|
||||
makeTimeColumn,
|
||||
makeGroupColumn,
|
||||
makeColumn,
|
||||
makeColumnsPlanFact,
|
||||
makeFilterTextMatch,
|
||||
makeNumericRender,
|
||||
makeNumericColumn,
|
||||
makeNumericColumnOptions,
|
||||
makeNumericColumnPlanFact,
|
||||
makeNumericStartEnd,
|
||||
makeNumericMinMax,
|
||||
makeSelectColumn,
|
||||
makeTagColumn,
|
||||
makeTagInput,
|
||||
makeTextColumn,
|
||||
makeTimezoneColumn,
|
||||
makeTimezoneRenderer,
|
||||
} from './Columns'
|
||||
|
||||
export type {
|
||||
DataType,
|
||||
RenderMethod,
|
||||
SorterMethod,
|
||||
TagInputProps,
|
||||
columnPropsOther,
|
||||
} from './Columns'
|
||||
export type { DateRangeWrapperProps } from './DateRangeWrapper'
|
||||
export type { DatePickerWrapperProps } from './DatePickerWrapper'
|
||||
export type { TimePickerWrapperProps } from './TimePickerWrapper'
|
||||
export type { BaseTableColumn, TableColumns, TableContainer } from './Table'
|
||||
export * from './sorters'
|
||||
export * from './EditableTable'
|
||||
export * from './DatePickerWrapper'
|
||||
export * from './TimePickerWrapper'
|
||||
export * from './DateRangeWrapper'
|
||||
export * from './Table'
|
||||
export * from './Columns'
|
||||
|
||||
export const defaultPagination = {
|
||||
defaultPageSize: 14,
|
||||
showSizeChanger: true,
|
||||
}
|
||||
|
||||
type PaginationContainer = {
|
||||
export type PaginationContainer<T> = {
|
||||
skip?: number
|
||||
take?: number
|
||||
count?: number
|
||||
items?: any[] | null
|
||||
items?: T[] | null
|
||||
}
|
||||
|
||||
export const makePaginationObject = (сontainer: PaginationContainer, ...other: any) => ({
|
||||
export const makePaginationObject = <T, M extends object>(сontainer: PaginationContainer<T>, other: M) => ({
|
||||
...other,
|
||||
pageSize: сontainer.take,
|
||||
total: сontainer.count ?? сontainer.items?.length ?? 0,
|
||||
|
@ -1,4 +1,2 @@
|
||||
export * from './D3Chart'
|
||||
export type { D3ChartProps } from './D3Chart'
|
||||
|
||||
export * from './types'
|
||||
|
@ -1,6 +1,3 @@
|
||||
export type { PointerIconColors, PointerIconProps } from './PointerIcon'
|
||||
export type { WellIconColors, WellIconProps, WellIconState } from './WellIcon'
|
||||
|
||||
export { PointerIcon } from './PointerIcon'
|
||||
export { WellIcon } from './WellIcon'
|
||||
export { Loader } from './Loader'
|
||||
export * from './PointerIcon'
|
||||
export * from './WellIcon'
|
||||
export * from './Loader'
|
||||
|
@ -1,14 +1,7 @@
|
||||
export type { PermissionViewProps } from './PermissionView'
|
||||
export type { TelemetryViewProps } from './TelemetryView'
|
||||
export type { CompanyViewProps } from './CompanyView'
|
||||
export type { RoleViewProps } from './RoleView'
|
||||
export type { UserViewProps } from './UserView'
|
||||
export type { WirelineViewProps } from './WirelineView'
|
||||
|
||||
export { PermissionView } from './PermissionView'
|
||||
export { TelemetryView, getTelemetryLabel } from './TelemetryView'
|
||||
export { CompanyView } from './CompanyView'
|
||||
export { RoleView } from './RoleView'
|
||||
export { UserView } from './UserView'
|
||||
export { WirelineView } from './WirelineView'
|
||||
export * from './PermissionView'
|
||||
export * from './TelemetryView'
|
||||
export * from './CompanyView'
|
||||
export * from './RoleView'
|
||||
export * from './UserView'
|
||||
export * from './WirelineView'
|
||||
export * from './WellView'
|
||||
|
@ -1,5 +1,2 @@
|
||||
export { WidgetSettingsWindow } from './WidgetSettingsWindow'
|
||||
export { BaseWidget } from './BaseWidget'
|
||||
|
||||
export type { WidgetSettingsWindowProps } from './WidgetSettingsWindow'
|
||||
export type { WidgetSettings, BaseWidgetProps } from './BaseWidget'
|
||||
export * from './WidgetSettingsWindow'
|
||||
export * from './BaseWidget'
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
import reportWebVitals from './reportWebVitals'
|
||||
import App from './App'
|
||||
|
||||
import '@styles/index.css'
|
||||
@ -14,8 +13,3 @@ root.render(
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals()
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
} from '@components/Table'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { AdminClusterService, AdminDepositService } from '@api'
|
||||
import { arrayOrDefault, coordsFormat, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, coordsFormat, withPermissions } from '@utils'
|
||||
import { min1 } from '@utils/validationRules'
|
||||
|
||||
const ClusterController = memo(() => {
|
||||
@ -112,8 +112,4 @@ const ClusterController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(ClusterController, {
|
||||
requirements: ['AdminDeposit.get', 'AdminCluster.get'],
|
||||
title: 'Кусты',
|
||||
route: 'cluster',
|
||||
})
|
||||
export default withPermissions(ClusterController, ['AdminDeposit.get', 'AdminCluster.get'])
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from '@components/Table'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { AdminCompanyService, AdminCompanyTypeService } from '@api'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { min1 } from '@utils/validationRules'
|
||||
|
||||
const CompanyController = memo(() => {
|
||||
@ -103,8 +103,4 @@ const CompanyController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(CompanyController, {
|
||||
requirements: ['AdminCompany.get', 'AdminCompanyType.get'],
|
||||
title: 'Компании',
|
||||
route: 'company',
|
||||
})
|
||||
export default withPermissions(CompanyController, ['AdminCompany.get', 'AdminCompanyType.get'])
|
||||
|
@ -3,7 +3,7 @@ import { Input } from 'antd'
|
||||
|
||||
import { EditableTable, makeColumn, makeStringSorter, defaultPagination } from '@components/Table'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { min1 } from '@utils/validationRules'
|
||||
import { AdminCompanyTypeService } from '@api'
|
||||
|
||||
@ -81,8 +81,4 @@ const CompanyTypeController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(CompanyTypeController, {
|
||||
requirements: ['AdminCompanyType.get'],
|
||||
title: 'Типы компаний',
|
||||
route: 'company_type',
|
||||
})
|
||||
export default withPermissions(CompanyTypeController, ['AdminCompanyType.get'])
|
||||
|
@ -3,7 +3,7 @@ import { Input } from 'antd'
|
||||
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { EditableTable, makeColumn, defaultPagination, makeTimezoneColumn } from '@components/Table'
|
||||
import { arrayOrDefault, coordsFormat, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, coordsFormat, withPermissions } from '@utils'
|
||||
import { min1 } from '@utils/validationRules'
|
||||
import { AdminDepositService } from '@api'
|
||||
|
||||
@ -81,8 +81,4 @@ const DepositController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(DepositController, {
|
||||
requirements: ['AdminDeposit.get'],
|
||||
title: 'Месторождения',
|
||||
route: 'deposit',
|
||||
})
|
||||
export default withPermissions(DepositController, ['AdminDeposit.get'])
|
||||
|
@ -3,7 +3,7 @@ import { Input } from 'antd'
|
||||
|
||||
import { EditableTable, makeColumn, makeStringSorter } from '@components/Table'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { min1 } from '@utils/validationRules'
|
||||
import { AdminPermissionService } from '@api'
|
||||
|
||||
@ -88,8 +88,4 @@ const PermissionController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(PermissionController, {
|
||||
requirements: ['AdminPermission.get'],
|
||||
title: 'Разрешения',
|
||||
route: 'permission',
|
||||
})
|
||||
export default withPermissions(PermissionController, ['AdminPermission.get'])
|
||||
|
@ -5,7 +5,7 @@ import { PermissionView, RoleView } from '@components/views'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { EditableTable, makeTagColumn, makeTextColumn } from '@components/Table'
|
||||
import { AdminPermissionService, AdminUserRoleService } from '@api'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { min1 } from '@utils/validationRules'
|
||||
|
||||
const RoleController = memo(() => {
|
||||
@ -95,8 +95,4 @@ const RoleController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(RoleController, {
|
||||
requirements: ['AdminPermission.get', 'AdminUserRole.get'],
|
||||
title: 'Роли',
|
||||
route: 'role',
|
||||
})
|
||||
export default withPermissions(RoleController, ['AdminPermission.get', 'AdminUserRole.get'])
|
||||
|
@ -8,7 +8,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import { lables } from '@components/views/TelemetryView'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import TelemetrySelect from '@components/selectors/TelemetrySelect'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { AdminTelemetryService } from '@api'
|
||||
|
||||
const { Item } = Descriptions
|
||||
@ -134,9 +134,4 @@ const TelemetryMerger = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(TelemetryMerger, {
|
||||
requirements: [],
|
||||
title: 'Объединение',
|
||||
route: 'merger',
|
||||
key: 'merger',
|
||||
})
|
||||
export default withPermissions(TelemetryMerger)
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from '@components/Table'
|
||||
import Poprompt from '@components/selectors/Poprompt'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { AdminTelemetryService } from '@api'
|
||||
|
||||
const TelemetryController = memo(() => {
|
||||
@ -121,9 +121,4 @@ const TelemetryController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(TelemetryController, {
|
||||
requirements: [],
|
||||
title: 'Просмотр',
|
||||
route: 'viewer',
|
||||
key: 'viewer',
|
||||
})
|
||||
export default withPermissions(TelemetryController)
|
||||
|
@ -2,7 +2,7 @@ import { memo, useMemo } from 'react'
|
||||
import { Outlet } from 'react-router-dom'
|
||||
|
||||
import { RootPathContext, useRootPath } from '@asb/context'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
const Telemetry = memo(() => {
|
||||
const root = useRootPath()
|
||||
@ -15,9 +15,4 @@ const Telemetry = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Telemetry, {
|
||||
requirements: ['AdminTelemetry.get'],
|
||||
title: 'Телеметрия',
|
||||
key: 'telemetry',
|
||||
route: 'telemetry/*',
|
||||
})
|
||||
export default withPermissions(Telemetry, ['AdminTelemetry.get'])
|
||||
|
@ -17,7 +17,7 @@ import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { AdminCompanyService, AdminUserRoleService, AdminUserService } from '@api'
|
||||
import { createLoginRules, nameRules, phoneRules, emailRules } from '@utils/validationRules'
|
||||
import { makeTextOnFilter, makeTextFilters, makeArrayOnFilter } from '@utils/filters'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
|
||||
import RoleTag from './RoleTag'
|
||||
|
||||
@ -227,8 +227,4 @@ const UserController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(UserController, {
|
||||
requirements: ['AdminUser.get', 'AdminCompany.get', 'AdminUserRole.get'],
|
||||
title: 'Пользователи',
|
||||
route: 'user',
|
||||
})
|
||||
export default withPermissions(UserController, ['AdminUser.get', 'AdminCompany.get', 'AdminUserRole.get'])
|
||||
|
@ -3,7 +3,7 @@ import { Input } from 'antd'
|
||||
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { defaultPagination, makeColumn, makeDateSorter, makeStringSorter, Table } from '@components/Table'
|
||||
import { arrayOrDefault, formatDate, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, formatDate, withPermissions } from '@utils'
|
||||
import { RequestTrackerService } from '@api'
|
||||
|
||||
const logRecordCount = 1000
|
||||
@ -65,8 +65,4 @@ const VisitLog = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(VisitLog, {
|
||||
requirements: ['RequestTracker.get'],
|
||||
title: 'Журнал посещений',
|
||||
route: 'visit_log',
|
||||
})
|
||||
export default withPermissions(VisitLog, ['RequestTracker.get'])
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { TelemetryView, CompanyView } from '@components/views'
|
||||
import TelemetrySelect from '@components/selectors/TelemetrySelect'
|
||||
import { arrayOrDefault, coordsFormat, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, coordsFormat, withPermissions } from '@utils'
|
||||
|
||||
const wellTypes = [
|
||||
{ value: 1, label: 'Наклонно-направленная' },
|
||||
@ -160,8 +160,4 @@ const WellController = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(WellController, {
|
||||
requirements: ['AdminCluster.get', 'AdminCompany.get', 'AdminTelemetry.get', 'AdminWell.get'],
|
||||
title: 'Скважины',
|
||||
route: 'well',
|
||||
})
|
||||
export default withPermissions(WellController, ['AdminCluster.get', 'AdminCompany.get', 'AdminTelemetry.get', 'AdminWell.get'])
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { Navigate, Route, Routes } from 'react-router-dom'
|
||||
import { lazy, memo, useMemo } from 'react'
|
||||
import { Navigate, Route, Routes, useLocation } from 'react-router-dom'
|
||||
import { lazy, memo, useEffect, useMemo } from 'react'
|
||||
|
||||
import { RootPathContext, useLayoutProps, useRootPath } from '@asb/context'
|
||||
import { MenuBreadcrumbItems } from '@components/MenuBreadcrumb'
|
||||
import { NoAccessComponent, wrapPrivateComponent } from '@utils'
|
||||
import { FastRunMenu } from '@components/FastRunMenu'
|
||||
import { makeMenuBreadcrumbItems } from '@components/MenuBreadcrumb'
|
||||
import { NoAccessComponent, withPermissions } from '@utils'
|
||||
|
||||
import { AdminNavigationMenu, menuItems } from './AdminNavigationMenu'
|
||||
|
||||
@ -20,21 +21,25 @@ const TelemetryViewer = lazy(() => import('./Telemetry/TelemetryViewer'))
|
||||
const TelemetryMerger = lazy(() => import('./Telemetry/TelemetryMerger'))
|
||||
const VisitLog = lazy(() => import('./VisitLog'))
|
||||
|
||||
const layoutProps = {
|
||||
sider: <AdminNavigationMenu />,
|
||||
title: 'Администраторская панель',
|
||||
isAdmin: true,
|
||||
breadcrumb: <MenuBreadcrumbItems menuItems={menuItems} pathRoot={/^\/admin\//} />,
|
||||
}
|
||||
|
||||
const AdminPanel = memo(() => {
|
||||
const location = useLocation()
|
||||
const root = useRootPath()
|
||||
const rootPath = useMemo(() => `${root}/admin`, [root])
|
||||
|
||||
useLayoutProps(layoutProps)
|
||||
const setLayoutProps = useLayoutProps()
|
||||
|
||||
useEffect(() => {
|
||||
setLayoutProps({
|
||||
sider: <AdminNavigationMenu />,
|
||||
title: 'Администраторская панель',
|
||||
isAdmin: true,
|
||||
breadcrumb: makeMenuBreadcrumbItems(menuItems, location.pathname, /^\/admin\//),
|
||||
})
|
||||
}, [location.pathname])
|
||||
|
||||
return (
|
||||
<RootPathContext.Provider value={rootPath}>
|
||||
<FastRunMenu />
|
||||
<Routes>
|
||||
<Route index element={<Navigate to={'visit_log'} replace />} />
|
||||
<Route path={'*'} element={<NoAccessComponent />} />
|
||||
@ -58,4 +63,4 @@ const AdminPanel = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(AdminPanel, { requirements: ['RequestTracker.get'] })
|
||||
export default withPermissions(AdminPanel, ['RequestTracker.get'])
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
calcAndUpdateStatsBySections,
|
||||
isRawDate,
|
||||
makeFilterMinMaxFunction,
|
||||
wrapPrivateComponent
|
||||
withPermissions
|
||||
} from '@utils'
|
||||
|
||||
const Tvd = lazy(() => import('@pages/Well/WellOperations/Tvd'))
|
||||
@ -219,8 +219,4 @@ const ClusterWells = memo(({ statsWells }) => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(ClusterWells, {
|
||||
requirements: [],
|
||||
title: 'Статистика по скважинам',
|
||||
route: 'wells',
|
||||
})
|
||||
export default withPermissions(ClusterWells)
|
||||
|
@ -3,8 +3,9 @@ import { useParams } from 'react-router-dom'
|
||||
|
||||
import { useLayoutProps } from '@asb/context'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { FastRunMenu } from '@components/FastRunMenu'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { OperationStatService } from '@api'
|
||||
|
||||
import ClusterWells from './ClusterWells'
|
||||
@ -34,15 +35,13 @@ const Cluster = memo(() => {
|
||||
}, [idCluster])
|
||||
|
||||
return (
|
||||
<LoaderPortal show={showLoader}>
|
||||
<ClusterWells statsWells={data} />
|
||||
</LoaderPortal>
|
||||
<>
|
||||
<FastRunMenu />
|
||||
<LoaderPortal show={showLoader}>
|
||||
<ClusterWells statsWells={data} />
|
||||
</LoaderPortal>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Cluster, {
|
||||
requirements: ['OperationStat.get'],
|
||||
title: 'Анализ скважин куста',
|
||||
route: 'cluster/:idCluster/*',
|
||||
key: 'cluster',
|
||||
})
|
||||
export default withPermissions(Cluster, ['OperationStat.get'])
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Map, Overlay } from 'pigeon-maps'
|
||||
import { useState, useEffect, memo, useMemo } from 'react'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { Map, Overlay } from 'pigeon-maps'
|
||||
import { Popover, Badge } from 'antd'
|
||||
|
||||
import { useLayoutProps } from '@asb/context'
|
||||
import { PointerIcon } from '@components/icons'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { FastRunMenu } from '@components/FastRunMenu'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, limitValue, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, limitValue, withPermissions } from '@utils'
|
||||
import { DepositService } from '@api'
|
||||
|
||||
import '@styles/index.css'
|
||||
@ -81,41 +82,39 @@ const Deposit = memo(() => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<LoaderPortal show={showLoader}>
|
||||
<div className={'h-100vh'} style={{ overflow: 'hidden' }}>
|
||||
<Map {...viewParams}>
|
||||
{depositsData.map(deposit => (
|
||||
<Overlay
|
||||
width={32}
|
||||
anchor={[deposit.latitude, deposit.longitude]}
|
||||
key={`${deposit.latitude} ${deposit.longitude}`}
|
||||
>
|
||||
<Popover content={
|
||||
<div>
|
||||
{deposit.clusters.map(cluster => (
|
||||
<Link key={cluster.id} to={{ pathname: `/cluster/${cluster.id}`, state: { from: location.pathname }}}>
|
||||
<div>{cluster.caption}</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
} trigger={['click']} title={deposit.caption}>
|
||||
<div style={{cursor: 'pointer'}}>
|
||||
<Badge count={deposit.clusters.length}>
|
||||
<PointerIcon state={'active'} width={48} height={59} />
|
||||
</Badge>
|
||||
</div>
|
||||
</Popover>
|
||||
</Overlay>
|
||||
))}
|
||||
</Map>
|
||||
</div>
|
||||
</LoaderPortal>
|
||||
<>
|
||||
<FastRunMenu />
|
||||
<LoaderPortal show={showLoader}>
|
||||
<div className={'h-100vh'} style={{ overflow: 'hidden' }}>
|
||||
<Map {...viewParams}>
|
||||
{depositsData.map(deposit => (
|
||||
<Overlay
|
||||
width={32}
|
||||
anchor={[deposit.latitude, deposit.longitude]}
|
||||
key={`${deposit.latitude} ${deposit.longitude}`}
|
||||
>
|
||||
<Popover content={
|
||||
<div>
|
||||
{deposit.clusters.map(cluster => (
|
||||
<Link key={cluster.id} to={{ pathname: `/cluster/${cluster.id}`, state: { from: location.pathname }}}>
|
||||
<div>{cluster.caption}</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
} trigger={['click']} title={deposit.caption}>
|
||||
<div style={{cursor: 'pointer'}}>
|
||||
<Badge count={deposit.clusters.length}>
|
||||
<PointerIcon state={'active'} width={48} height={59} />
|
||||
</Badge>
|
||||
</div>
|
||||
</Popover>
|
||||
</Overlay>
|
||||
))}
|
||||
</Map>
|
||||
</div>
|
||||
</LoaderPortal>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Deposit, {
|
||||
requirements: ['Cluster.get'],
|
||||
title: 'Месторождение',
|
||||
route: 'deposit/*',
|
||||
key: 'deposit',
|
||||
})
|
||||
export default withPermissions(Deposit, ['Cluster.get'])
|
||||
|
@ -4,7 +4,7 @@ import { InfoCircleFilled, CloseCircleOutlined } from '@ant-design/icons'
|
||||
import { Button, Result, Typography } from 'antd'
|
||||
|
||||
import { downloadFile, invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
import { FileService } from '@api'
|
||||
|
||||
const { Paragraph, Text } = Typography
|
||||
@ -92,7 +92,4 @@ const FileDownload = memo(function FileDownload() {
|
||||
|
||||
FileDownload.displayName = 'FileDownloadMemo'
|
||||
|
||||
export default wrapPrivateComponent(FileDownload, {
|
||||
requirements: ['File.get'],
|
||||
route: 'file_download/:idFile/*',
|
||||
})
|
||||
export default withPermissions(FileDownload, ['File.get'])
|
||||
|
@ -7,7 +7,7 @@ import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { WellSelector } from '@components/selectors/WellSelector'
|
||||
import { makeGroupColumn, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table'
|
||||
import { OperationStatService, WellOperationService } from '@api'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
|
||||
import '@styles/index.css'
|
||||
import '@styles/statistics.less'
|
||||
@ -242,8 +242,4 @@ const Statistics = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Statistics, {
|
||||
requirements: [],
|
||||
title: 'Оценка по ЦБ',
|
||||
route: 'statistics',
|
||||
})
|
||||
export default withPermissions(Statistics)
|
||||
|
@ -10,7 +10,7 @@ import { makeTextColumn, makeNumericColumnPlanFact, makeNumericColumn } from '@c
|
||||
import { WellCompositeService } from '@api'
|
||||
import {
|
||||
hasPermission,
|
||||
wrapPrivateComponent,
|
||||
withPermissions,
|
||||
calcAndUpdateStatsBySections,
|
||||
makeFilterMinMaxFunction,
|
||||
getOperations
|
||||
@ -267,8 +267,4 @@ const WellCompositeSections = memo(({ statsWells, selectedSections }) => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(WellCompositeSections, {
|
||||
requirements: ['WellComposite.get'],
|
||||
title: 'Статистика по секциям',
|
||||
route: 'sections',
|
||||
})
|
||||
export default withPermissions(WellCompositeSections, ['WellComposite.get'])
|
||||
|
@ -7,7 +7,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import SuspenseFallback from '@components/SuspenseFallback'
|
||||
import WellSelector from '@components/selectors/WellSelector'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, NoAccessComponent, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, NoAccessComponent, withPermissions } from '@utils'
|
||||
import { OperationStatService, WellCompositeService } from '@api'
|
||||
|
||||
import WellCompositeSections from './WellCompositeSections'
|
||||
@ -76,4 +76,4 @@ const WellCompositeEditor = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(WellCompositeEditor, { requirements: ['OperationStat.get', 'WellComposite.get'] })
|
||||
export default withPermissions(WellCompositeEditor, ['OperationStat.get', 'WellComposite.get'])
|
||||
|
@ -2,7 +2,7 @@ import { memo, useMemo } from 'react'
|
||||
import { Outlet } from 'react-router-dom'
|
||||
|
||||
import { RootPathContext, useRootPath } from '@asb/context'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
const Analytics = memo(() => {
|
||||
const root = useRootPath()
|
||||
@ -15,9 +15,4 @@ const Analytics = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Analytics, {
|
||||
requirements: [],
|
||||
title: 'Аналитика',
|
||||
route: 'analytics/*',
|
||||
key: 'analytics',
|
||||
})
|
||||
export default withPermissions(Analytics)
|
||||
|
@ -2,7 +2,7 @@ import { Navigate, Route, Routes } from 'react-router-dom'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import { RootPathContext, useRootPath } from '@asb/context'
|
||||
import { wrapPrivateComponent, NoAccessComponent, hasPermission } from '@utils'
|
||||
import { withPermissions, NoAccessComponent, hasPermission } from '@utils'
|
||||
|
||||
import DocumentsTemplate from './DocumentsTemplate'
|
||||
|
||||
@ -48,9 +48,4 @@ const MenuDocuments = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(MenuDocuments, {
|
||||
requirements: [ 'Deposit.get', 'File.get' ],
|
||||
title: 'Документы',
|
||||
route: 'document/*',
|
||||
key: 'document',
|
||||
})
|
||||
export default withPermissions(MenuDocuments, [ 'Deposit.get', 'File.get' ])
|
||||
|
@ -13,7 +13,7 @@ import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useWell } from '@asb/context'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { downloadFile, formatBytes, invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { arrayOrDefault, formatDate, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, formatDate, withPermissions } from '@utils'
|
||||
import { DrillingProgramService } from '@api'
|
||||
|
||||
import CategoryAdder from './CategoryAdder'
|
||||
@ -185,8 +185,4 @@ const DrillingProgram = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(DrillingProgram, {
|
||||
requirements: [ 'DrillingProgram.get' ],
|
||||
title: 'Программа бурения',
|
||||
route: 'drillingProgram',
|
||||
})
|
||||
export default withPermissions(DrillingProgram, [ 'DrillingProgram.get' ])
|
||||
|
@ -5,7 +5,7 @@ import { Button } from 'antd'
|
||||
import { useWell } from '@asb/context'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
import { MeasureService } from '@api'
|
||||
|
||||
import { MeasureTable } from './MeasureTable'
|
||||
@ -93,8 +93,4 @@ const Measure = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Measure, {
|
||||
requirements: [ 'Measure.get' ],
|
||||
title: 'Измерения',
|
||||
route: 'measure',
|
||||
})
|
||||
export default withPermissions(Measure, [ 'Measure.get' ])
|
||||
|
@ -7,7 +7,7 @@ import { useWell } from '@asb/context'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { DateRangeWrapper, Table, makeDateColumn, makeColumn } from '@components/Table'
|
||||
import { download, invokeWebApiWrapperAsync, notify } from '@components/factory'
|
||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, withPermissions } from '@utils'
|
||||
import { DailyReportService } from '@api'
|
||||
|
||||
import ReportEditor from './ReportEditor'
|
||||
@ -123,10 +123,4 @@ const DailyReport = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(DailyReport, {
|
||||
requirements: [
|
||||
// 'DailyReport.get',
|
||||
],
|
||||
title: 'Суточный рапорт',
|
||||
route: 'daily_report',
|
||||
})
|
||||
export default withPermissions(DailyReport) //, ['DailyReport.get'])
|
||||
|
@ -7,7 +7,7 @@ import { useWell } from '@asb/context'
|
||||
import { DateRangeWrapper } from 'components/Table'
|
||||
import { LoaderPortal } from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { formatDate, wrapPrivateComponent } from '@utils'
|
||||
import { formatDate, withPermissions } from '@utils'
|
||||
import { Subscribe } from '@services/signalr'
|
||||
import { ReportService } from '@api'
|
||||
|
||||
@ -175,8 +175,4 @@ const DiagramReport = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(DiagramReport, {
|
||||
requirements: [ 'Report.get' ],
|
||||
title: 'Диаграмма',
|
||||
route: 'diagram_report',
|
||||
})
|
||||
export default withPermissions(DiagramReport, [ 'Report.get' ])
|
||||
|
@ -2,7 +2,7 @@ import { Outlet } from 'react-router-dom'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import { RootPathContext, useRootPath } from '@asb/context'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
const Reports = memo(() => {
|
||||
const root = useRootPath()
|
||||
@ -15,9 +15,4 @@ const Reports = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Reports, {
|
||||
requirements: [],
|
||||
title: 'Рапорта',
|
||||
route: 'reports/*',
|
||||
key: 'reports',
|
||||
})
|
||||
export default withPermissions(Reports)
|
||||
|
@ -11,7 +11,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { DatePickerWrapper, makeDateSorter } from '@components/Table'
|
||||
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
||||
import { formatDate, range, wrapPrivateComponent } from '@utils'
|
||||
import { formatDate, range, withPermissions } from '@utils'
|
||||
import { TelemetryDataSaubService } from '@api'
|
||||
|
||||
import { makeChartGroups, normalizeData, yAxis } from '../TelemetryView'
|
||||
@ -265,8 +265,4 @@ const Archive = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Archive, {
|
||||
requirements: ['TelemetryDataSaub.get'],
|
||||
title: 'Архив',
|
||||
route: 'archive',
|
||||
})
|
||||
export default withPermissions(Archive, ['TelemetryDataSaub.get'])
|
||||
|
@ -7,7 +7,7 @@ import { useWell, useRootPath } from '@asb/context'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { BaseWidget, WidgetSettingsWindow } from '@components/widgets'
|
||||
import { arrayOrDefault, wrapPrivateComponent, getJSON, setJSON, getTabname } from '@utils'
|
||||
import { arrayOrDefault, withPermissions, getJSON, setJSON, getTabname } from '@utils'
|
||||
import Subscribe from '@services/signalr'
|
||||
import {
|
||||
WitsInfoService,
|
||||
@ -260,17 +260,12 @@ const DashboardNNB = memo(({ enableEditing = false }) => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(DashboardNNB, {
|
||||
requirements: [
|
||||
// 'WitsInfo',
|
||||
// 'WitsRecord1',
|
||||
// 'WitsRecord7',
|
||||
// 'WitsRecord8',
|
||||
// 'WitsRecord50',
|
||||
// 'WitsRecord60',
|
||||
// 'WitsRecord61',
|
||||
],
|
||||
title: 'ННБ',
|
||||
route: 'dashboard_nnb/*',
|
||||
key: 'dashboard_nnb',
|
||||
})
|
||||
export default withPermissions(DashboardNNB, [
|
||||
// 'WitsInfo',
|
||||
// 'WitsRecord1',
|
||||
// 'WitsRecord7',
|
||||
// 'WitsRecord8',
|
||||
// 'WitsRecord50',
|
||||
// 'WitsRecord60',
|
||||
// 'WitsRecord61',
|
||||
])
|
||||
|
@ -8,7 +8,7 @@ import { useWell } from '@asb/context'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { makeColumn, makeDateColumn, makeNumericColumn, makeNumericSorter, makeTextColumn, Table } from '@components/Table'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
import { MessageService } from '@api'
|
||||
|
||||
import '@styles/filter.less'
|
||||
@ -147,8 +147,4 @@ const Messages = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Messages, {
|
||||
requirements: ['Message.get'],
|
||||
title: 'Сообщения',
|
||||
route: 'messages',
|
||||
})
|
||||
export default withPermissions(Messages, ['Message.get'])
|
||||
|
@ -7,7 +7,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import D3HorizontalPercentChart from '@components/d3/D3HorizontalPercentChart'
|
||||
import { DateRangeWrapper, makeColumn, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table'
|
||||
import { arrayOrDefault, range, wrapPrivateComponent } from '@utils'
|
||||
import { arrayOrDefault, range, withPermissions } from '@utils'
|
||||
import { SubsystemOperationTimeService } from '@api'
|
||||
|
||||
import '@styles/filter.less'
|
||||
@ -121,9 +121,4 @@ export const OperationTime = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(OperationTime, {
|
||||
requirements: [], // SubsystemOperationTime.get
|
||||
title: 'Наработка',
|
||||
route: 'operation_time',
|
||||
key: 'operation_time',
|
||||
})
|
||||
export default withPermissions(OperationTime) //, ['SubsystemOperationTime.get'])
|
||||
|
@ -7,7 +7,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import { DateRangeWrapper } from '@components/Table'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { unique } from '@utils/filters'
|
||||
import { getPermissions, arrayOrDefault, range, wrapPrivateComponent, pretify } from '@utils'
|
||||
import { getPermissions, arrayOrDefault, range, withPermissions, pretify } from '@utils'
|
||||
import { DetectedOperationService, DrillerService, TelemetryDataSaubService } from '@api'
|
||||
|
||||
import DrillerList from './DrillerList'
|
||||
@ -161,4 +161,4 @@ const Operations = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Operations, { requirements: ['DetectedOperation.get', 'TelemetryDataSaub.get'] })
|
||||
export default withPermissions(Operations, ['DetectedOperation.get', 'TelemetryDataSaub.get'])
|
||||
|
@ -9,7 +9,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import { Grid, GridItem } from '@components/Grid'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
||||
import { formatDate, hasPermission, wrapPrivateComponent } from '@utils'
|
||||
import { formatDate, hasPermission, withPermissions } from '@utils'
|
||||
import { Subscribe } from '@services/signalr'
|
||||
import {
|
||||
DrillFlowChartService,
|
||||
@ -312,14 +312,10 @@ const TelemetryView = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(TelemetryView, {
|
||||
requirements: [
|
||||
'DrillFlowChart.get',
|
||||
'OperationStat.get',
|
||||
'TelemetryDataSaub.get',
|
||||
'TelemetryDataSpin.get',
|
||||
'Well.get',
|
||||
],
|
||||
title: 'Мониторинг',
|
||||
route: 'telemetry',
|
||||
})
|
||||
export default withPermissions(TelemetryView, [
|
||||
'DrillFlowChart.get',
|
||||
'OperationStat.get',
|
||||
'TelemetryDataSaub.get',
|
||||
'TelemetryDataSpin.get',
|
||||
'Well.get',
|
||||
])
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { FundViewOutlined } from '@ant-design/icons'
|
||||
import { Outlet } from 'react-router-dom'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import { RootPathContext, useRootPath } from '@asb/context'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
import '@styles/index.css'
|
||||
|
||||
@ -18,10 +17,4 @@ const Telemetry = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Telemetry, {
|
||||
requirements: [],
|
||||
icon: <FundViewOutlined />,
|
||||
title: 'Телеметрия',
|
||||
route: 'telemetry/*',
|
||||
key: 'telemetry',
|
||||
})
|
||||
export default withPermissions(Telemetry)
|
||||
|
@ -9,7 +9,7 @@ import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { makeColumn, makeDateColumn, makeTextColumn, Table } from '@components/Table'
|
||||
import { WellFinalDocumentsService } from '@api'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
import WellCaseEditor from './WellCaseEditor'
|
||||
import { HistoryTable } from './HistoryTable'
|
||||
@ -102,9 +102,4 @@ const WellCase = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(WellCase, {
|
||||
title: 'Дело скважины',
|
||||
route: 'well_case',
|
||||
requirements: [],
|
||||
// requirements: ['WellFinalDocuments.get'],
|
||||
})
|
||||
export default withPermissions(WellCase) //, ['WellFinalDocuments.get'])
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
import WellOperationsEditor from './WellOperationsEditor'
|
||||
|
||||
export const WellOperationsEditorFact = wrapPrivateComponent(
|
||||
export const WellOperationsEditorFact = withPermissions(
|
||||
() => <WellOperationsEditor idType={1} tableName={'well_operations_fact'}/>,
|
||||
{
|
||||
requirements: [ 'WellOperation.get' ],
|
||||
title: 'Факт',
|
||||
route: 'fact',
|
||||
}
|
||||
[ 'WellOperation.get' ],
|
||||
)
|
||||
|
||||
export default WellOperationsEditorFact
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
import WellOperationsEditor from './WellOperationsEditor'
|
||||
|
||||
export const WellOperationsEditorPlan = wrapPrivateComponent(
|
||||
export const WellOperationsEditorPlan = withPermissions(
|
||||
() => <WellOperationsEditor idType={0} tableName={'well_operations_plan'}/>,
|
||||
{
|
||||
requirements: [ 'WellOperation.get' ],
|
||||
title: 'План',
|
||||
route: 'plan',
|
||||
}
|
||||
[ 'WellOperation.get' ],
|
||||
)
|
||||
|
||||
export default WellOperationsEditorPlan
|
||||
|
@ -8,7 +8,7 @@ import { useTopRightBlock, useWell } from '@asb/context'
|
||||
import { D3Chart } from '@components/d3'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { formatDate, fractionalSum, wrapPrivateComponent, getOperations, pretify } from '@utils'
|
||||
import { formatDate, fractionalSum, withPermissions, getOperations, pretify } from '@utils'
|
||||
|
||||
import TLPie from './TLPie'
|
||||
import TLChart from './TLChart'
|
||||
@ -294,8 +294,4 @@ const Tvd = memo(({ well: givenWell, title, ...other }) => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Tvd, {
|
||||
requirements: ['OperationStat.get', 'DetectedOperation.get'],
|
||||
title: 'TVD',
|
||||
route: 'tvd',
|
||||
})
|
||||
export default withPermissions(Tvd, ['OperationStat.get', 'DetectedOperation.get'])
|
||||
|
@ -2,18 +2,11 @@ import { Outlet } from 'react-router-dom'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import { RootPathContext, useRootPath } from '@asb/context'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
|
||||
const properties = {
|
||||
requirements: [],
|
||||
title: 'Операции по скважине',
|
||||
route: 'operations/*',
|
||||
key: 'operations',
|
||||
}
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
const WellOperations = memo(() => {
|
||||
const root = useRootPath()
|
||||
const rootPath = useMemo(() => `${root}/${properties.key}`, [root])
|
||||
const rootPath = useMemo(() => `${root}/operations`, [root])
|
||||
|
||||
return(
|
||||
<RootPathContext.Provider value={rootPath}>
|
||||
@ -22,4 +15,4 @@ const WellOperations = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(WellOperations, properties)
|
||||
export default withPermissions(WellOperations)
|
||||
|
@ -2,9 +2,10 @@ import { lazy, memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { Navigate, Route, Routes, useLocation, useParams } from 'react-router-dom'
|
||||
|
||||
import { WellContext, RootPathContext, useRootPath, useLayoutProps, TopRightBlockContext } from '@asb/context'
|
||||
import { FastRunMenu } from '@components/FastRunMenu'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { MenuBreadcrumbItems } from '@components/MenuBreadcrumb'
|
||||
import { NoAccessComponent, wrapPrivateComponent } from '@utils'
|
||||
import { makeMenuBreadcrumbItems } from '@components/MenuBreadcrumb'
|
||||
import { NoAccessComponent, withPermissions } from '@utils'
|
||||
import { WellService } from '@api'
|
||||
|
||||
import { NavigationMenu, menuItems } from './NavigationMenu'
|
||||
@ -77,15 +78,16 @@ const Well = memo(() => {
|
||||
|
||||
useEffect(() => setLayoutProps({
|
||||
sider: <NavigationMenu idWell={well.id} />,
|
||||
breadcrumb: <MenuBreadcrumbItems menuItems={menuItems} pathRoot={/^\/well\/[0-9]+\//} />,
|
||||
breadcrumb: makeMenuBreadcrumbItems(menuItems, location.pathname, /^\/well\/[0-9]+\//),
|
||||
topRightBlock: topRightBlock,
|
||||
}), [well, setLayoutProps, topRightBlock])
|
||||
}), [well, location.pathname, setLayoutProps, topRightBlock])
|
||||
|
||||
useEffect(() => setTopRightBlock(undefined), [location])
|
||||
|
||||
return (
|
||||
<RootPathContext.Provider value={rootPath}>
|
||||
<WellContext.Provider value={[well, updateWell]}>
|
||||
<FastRunMenu />
|
||||
<TopRightBlockContext.Provider value={setTopRightBlock}>
|
||||
<Routes>
|
||||
<Route index element={<Navigate to={'telemetry'} replace />} />
|
||||
@ -138,9 +140,4 @@ const Well = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Well, {
|
||||
requirements: [],
|
||||
title: 'Скважина',
|
||||
route: 'well/:idWell/*',
|
||||
key: 'well',
|
||||
})
|
||||
export default withPermissions(Well)
|
||||
|
@ -6,7 +6,7 @@ import { Card, Form, Input, Button } from 'antd'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { loginRules, passwordRules } from '@utils/validationRules'
|
||||
import { setUser, wrapPrivateComponent } from '@utils'
|
||||
import { setUser, withPermissions } from '@utils'
|
||||
import { AuthService } from '@api'
|
||||
|
||||
import '@styles/index.css'
|
||||
@ -59,8 +59,4 @@ const Login = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Login, {
|
||||
requirements: [],
|
||||
title: 'Вход в систему',
|
||||
route: 'login',
|
||||
})
|
||||
export default withPermissions(Login)
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
passwordRules,
|
||||
phoneRules
|
||||
} from '@utils/validationRules'
|
||||
import { wrapPrivateComponent } from '@utils'
|
||||
import { withPermissions } from '@utils'
|
||||
|
||||
import Logo from '@images/Logo'
|
||||
|
||||
@ -92,8 +92,4 @@ export const Register = memo(() => {
|
||||
)
|
||||
})
|
||||
|
||||
export default wrapPrivateComponent(Register, {
|
||||
requirements: [],
|
||||
title: 'Регистрация',
|
||||
route: 'register',
|
||||
})
|
||||
export default withPermissions(Register)
|
||||
|
13
src/styles/fast_run_menu.less
Normal file
13
src/styles/fast_run_menu.less
Normal file
@ -0,0 +1,13 @@
|
||||
.fast-run-menu {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
top: 100px;
|
||||
left: calc(25vw - 5px);
|
||||
border: 5px solid #777;
|
||||
border-radius: 5px;
|
||||
width: 50vw;
|
||||
}
|
||||
|
||||
.fast-run-menu-text-found {
|
||||
background-color: yellow;
|
||||
}
|
@ -1,29 +1,12 @@
|
||||
export * from './arrayOrDefault'
|
||||
|
||||
export * from './datetime'
|
||||
export type { RawDate, TimezoneId, timeInS } from './datetime'
|
||||
|
||||
export * from './chart'
|
||||
|
||||
export * from './min_max_filter'
|
||||
export type { KeyType } from './min_max_filter'
|
||||
|
||||
export * from './objects'
|
||||
|
||||
export * from './numbers'
|
||||
|
||||
export * from './permissions'
|
||||
export type { Role, Permission, ServiceName, ServiceRequestType, PermissionRequest, PermissionRecord, PrivateProps } from './permissions'
|
||||
|
||||
export * from './saubOperations'
|
||||
export type { SaubData } from './saubOperations'
|
||||
|
||||
export * from './storage'
|
||||
export type { StorageNames, DataDashboardNNB } from './storage'
|
||||
|
||||
export * from './string'
|
||||
|
||||
export * from './svg'
|
||||
|
||||
export * from './table_settings'
|
||||
export type { TableColumnSettings, TableSettings, TableSettingsStore } from './table_settings'
|
||||
|
@ -87,17 +87,7 @@ export const publicPages: Readonly<string[]> = [
|
||||
'/register',
|
||||
]
|
||||
|
||||
export type PrivateProps = {
|
||||
key?: string
|
||||
icon?: ReactNode
|
||||
route?: string
|
||||
title?: ReactNode
|
||||
requirements?: string[]
|
||||
}
|
||||
|
||||
export type PrivateComponent<P extends object> = NamedExoticComponent<P> & PrivateProps & {
|
||||
getKey: () => string
|
||||
}
|
||||
export type PrivateComponent<P extends object> = NamedExoticComponent<P>
|
||||
|
||||
export const NoAccessComponent = memo(() => getUser().login ? (
|
||||
<AccessDenied /> // <Navigate to={'/access_denied'} replace />
|
||||
@ -105,18 +95,13 @@ export const NoAccessComponent = memo(() => getUser().login ? (
|
||||
<Navigate to={'/login'} replace />
|
||||
))
|
||||
|
||||
export const wrapPrivateComponent = <P extends object>(
|
||||
export const withPermissions = <P extends object>(
|
||||
Component: NamedExoticComponent<P> | ((props: P) => ReactElement),
|
||||
properties: PrivateProps = {},
|
||||
requirements: Permission[] = [],
|
||||
elseNode: JSX.Element = <NoAccessComponent />
|
||||
): PrivateComponent<P> => Object.assign(
|
||||
memo<P>((props) => hasPermission(properties.requirements) ? <Component {...props} /> : elseNode),
|
||||
{
|
||||
getKey() { return this.key ?? this.route ?? '' },
|
||||
requirements: [],
|
||||
...properties,
|
||||
}
|
||||
)
|
||||
): PrivateComponent<P> => Object.assign(memo<P>(function PrivateWrapper(props) {
|
||||
return hasPermission(requirements) ? <Component {...props} /> : elseNode
|
||||
}))
|
||||
|
||||
export const getTabname = () => {
|
||||
const params = useParams()
|
||||
|
@ -1,8 +1,4 @@
|
||||
export * from './cachedFetch'
|
||||
|
||||
export * from './functionalValue'
|
||||
export type { FunctionalValue } from './functionalValue'
|
||||
|
||||
export * from './usePartialProps'
|
||||
|
||||
export * from './useUserSettings'
|
||||
|
Loading…
Reference in New Issue
Block a user