forked from ddrilling/asb_cloud_front
Добавлены новые типы документов, косметика
This commit is contained in:
parent
efc7ae5e17
commit
df9eeae047
@ -1,22 +1,50 @@
|
|||||||
import { useState, useEffect } from "react"
|
import moment from 'moment'
|
||||||
import { DatePicker, Button, Input } from "antd"
|
import { useState, useEffect } from 'react'
|
||||||
import moment from "moment"
|
import { DatePicker, Button, Input } from 'antd'
|
||||||
import { FileService } from "../../services/api"
|
import { FileService } from '../../services/api'
|
||||||
import {
|
import { invokeWebApiWrapperAsync, downloadFile, formatBytes } from '../../components/factory'
|
||||||
invokeWebApiWrapperAsync,
|
import { EditableTable, makePaginationObject } from '../../components/Table'
|
||||||
downloadFile,
|
import { UploadForm } from '../../components/UploadForm'
|
||||||
formatBytes,
|
import LoaderPortal from '../../components/LoaderPortal'
|
||||||
} from "../../components/factory"
|
import { UserView } from '../../components/UserView'
|
||||||
import { EditableTable, makePaginationObject } from "../../components/Table"
|
import { CompanyView } from '../../components/CompanyView'
|
||||||
import {UploadForm} from "../../components/UploadForm"
|
|
||||||
import LoaderPortal from "../../components/LoaderPortal"
|
|
||||||
import {UserView} from '../../components/UserView'
|
|
||||||
import {CompanyView} from '../../components/CompanyView'
|
|
||||||
|
|
||||||
const pageSize = 12
|
const pageSize = 12
|
||||||
const { RangePicker } = DatePicker
|
const { RangePicker } = DatePicker
|
||||||
const { Search } = Input
|
const { Search } = Input
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'Документ',
|
||||||
|
key: 'document',
|
||||||
|
dataIndex: 'name',
|
||||||
|
render: (name, row) => (
|
||||||
|
<Button type={'link'} onClick={() => downloadFile(row)} download={name}>
|
||||||
|
{name}
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
}, {
|
||||||
|
title: 'Дата загрузки',
|
||||||
|
key: 'uploadDate',
|
||||||
|
dataIndex: 'uploadDate',
|
||||||
|
render: item => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss'),
|
||||||
|
}, {
|
||||||
|
title: 'Размер',
|
||||||
|
key: 'size',
|
||||||
|
dataIndex: 'size',
|
||||||
|
render: item => formatBytes(item)
|
||||||
|
}, {
|
||||||
|
title: 'Автор',
|
||||||
|
key: 'author',
|
||||||
|
dataIndex: 'author',
|
||||||
|
render: item => <UserView user={item}/>
|
||||||
|
}, {
|
||||||
|
title: 'Компания',
|
||||||
|
key: 'company',
|
||||||
|
render: (_, record) => <CompanyView company={record?.author?.company}/>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
export default function DocumentsTemplate({ idCategory, idWell, accept, headerChild, customColumns, beforeTable, onChange}) {
|
export default function DocumentsTemplate({ idCategory, idWell, accept, headerChild, customColumns, beforeTable, onChange}) {
|
||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const [filterDataRange, setFilterDataRange] = useState([])
|
const [filterDataRange, setFilterDataRange] = useState([])
|
||||||
@ -28,59 +56,17 @@ export default function DocumentsTemplate({ idCategory, idWell, accept, headerCh
|
|||||||
|
|
||||||
const uploadUrl = `/api/well/${idWell}/files/?idCategory=${idCategory}`
|
const uploadUrl = `/api/well/${idWell}/files/?idCategory=${idCategory}`
|
||||||
|
|
||||||
const handleUploadComplete = () => {
|
const handleUploadComplete = () => update()
|
||||||
update()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleFileDelete = async (file) => {
|
const handleFileDelete = async (file) => {
|
||||||
await FileService.delete(idWell, file.id)
|
await FileService.delete(idWell, file.id)
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
const hanleCompanySearch = (value, _) => {
|
const hanleCompanySearch = (value, _) => setFilterCompanyName(value)
|
||||||
setFilterCompanyName(value)
|
const hanleFileNameSearch = (value, _) => setFilterFileName(value)
|
||||||
}
|
|
||||||
|
|
||||||
const hanleFileNameSearch = (value, _) => {
|
const mergedColumns = [...columns, ...(customColumns ?? [])]
|
||||||
setFilterFileName(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: "Документ",
|
|
||||||
key: "document",
|
|
||||||
dataIndex: "name",
|
|
||||||
render: (name, row) => (
|
|
||||||
<Button type="link" onClick={() => downloadFile(row)} download={name}>
|
|
||||||
{name}
|
|
||||||
</Button>),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Дата загрузки",
|
|
||||||
key: "uploadDate",
|
|
||||||
dataIndex: "uploadDate",
|
|
||||||
render: item =>
|
|
||||||
moment.utc(item).local().format("DD MMM YYYY, HH:mm:ss"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Размер",
|
|
||||||
key: "size",
|
|
||||||
dataIndex: "size",
|
|
||||||
render: item => formatBytes(item)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Автор",
|
|
||||||
key: "author",
|
|
||||||
dataIndex: "author",
|
|
||||||
render: item => <UserView user={item}/>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Компания",
|
|
||||||
key: "company",
|
|
||||||
render: (_, record) => <CompanyView company={record?.author?.company}/>
|
|
||||||
},
|
|
||||||
...(customColumns??[])
|
|
||||||
]
|
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
let begin = null
|
let begin = null
|
||||||
@ -103,10 +89,9 @@ export default function DocumentsTemplate({ idCategory, idWell, accept, headerCh
|
|||||||
pageSize,
|
pageSize,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!paginatedFiles)
|
if (!paginatedFiles) return
|
||||||
return
|
|
||||||
|
|
||||||
const filesInfos = paginatedFiles.items??[]
|
const filesInfos = paginatedFiles.items ?? []
|
||||||
setFiles(filesInfos)
|
setFiles(filesInfos)
|
||||||
const newPagination = makePaginationObject(paginatedFiles)
|
const newPagination = makePaginationObject(paginatedFiles)
|
||||||
setPagination(newPagination)
|
setPagination(newPagination)
|
||||||
@ -117,28 +102,14 @@ export default function DocumentsTemplate({ idCategory, idWell, accept, headerCh
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(update, [idWell, idCategory, page, filterDataRange, filterCompanyName, filterFileName])
|
useEffect(update, [idWell, idCategory, page, filterDataRange, filterCompanyName, filterFileName])
|
||||||
useEffect(()=>{
|
useEffect(() => onChange?.(files), [files, onChange])
|
||||||
if(onChange)
|
|
||||||
onChange(files)
|
|
||||||
}, [files, onChange])
|
|
||||||
|
|
||||||
const companies = [...new Set(files.map(file=>file.company))]
|
const companies = [...new Set(files.map(file => file.company))].filter(company => company)
|
||||||
.filter(company=>company)
|
const filenames = [...new Set(files.map(file => file.name))].filter(name => name)
|
||||||
|
|
||||||
const DataListCompanies = <datalist id="listCompanies">
|
|
||||||
{companies.map((company)=><option key={company} value={company}>{company}</option>)}
|
|
||||||
</datalist>
|
|
||||||
|
|
||||||
const filenames = [...new Set(files.map(file=>file.name))]
|
|
||||||
.filter(name=>name)
|
|
||||||
|
|
||||||
const DataListFileNames = <datalist id="listFileNames">
|
|
||||||
{filenames.map((name)=><option key={name} value={name}>{name}</option>)}
|
|
||||||
</datalist>
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal show={showLoader}>
|
<LoaderPortal show={showLoader}>
|
||||||
<div style={{margin:16, display:'flex'}}>
|
<div style={{ margin: 16, display: 'flex' }}>
|
||||||
<div>
|
<div>
|
||||||
<span>Фильтр по дате</span>
|
<span>Фильтр по дате</span>
|
||||||
<div>
|
<div>
|
||||||
@ -149,19 +120,29 @@ export default function DocumentsTemplate({ idCategory, idWell, accept, headerCh
|
|||||||
<div>
|
<div>
|
||||||
<span>Фильтр по компании</span>
|
<span>Фильтр по компании</span>
|
||||||
<Search
|
<Search
|
||||||
list='listCompanies'
|
list={'listCompanies'}
|
||||||
placeholder="Фильтр по компании"
|
placeholder={'Фильтр по компании'}
|
||||||
onSearch={hanleCompanySearch}/>
|
onSearch={hanleCompanySearch}
|
||||||
{DataListCompanies}
|
/>
|
||||||
|
<datalist id={'listCompanies'}>
|
||||||
|
{companies.map((company) => (
|
||||||
|
<option key={company} value={company}>{company}</option>
|
||||||
|
))}
|
||||||
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span>Фильтр по имени файла</span>
|
<span>Фильтр по имени файла</span>
|
||||||
<Search
|
<Search
|
||||||
list='listFileNames'
|
list={'listFileNames'}
|
||||||
placeholder="Фильтр по имени файла"
|
placeholder={'Фильтр по имени файла'}
|
||||||
onSearch={hanleFileNameSearch}/>
|
onSearch={hanleFileNameSearch}
|
||||||
{DataListFileNames}
|
/>
|
||||||
|
<datalist id={'listFileNames'}>
|
||||||
|
{filenames.map((name) => (
|
||||||
|
<option key={name} value={name}>{name}</option>
|
||||||
|
))}
|
||||||
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -170,16 +151,17 @@ export default function DocumentsTemplate({ idCategory, idWell, accept, headerCh
|
|||||||
url={uploadUrl}
|
url={uploadUrl}
|
||||||
accept={accept}
|
accept={accept}
|
||||||
onUploadStart={() => setShowLoader(true)}
|
onUploadStart={() => setShowLoader(true)}
|
||||||
onUploadComplete={handleUploadComplete}/>
|
onUploadComplete={handleUploadComplete}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{headerChild}
|
{headerChild}
|
||||||
</div>
|
</div>
|
||||||
{beforeTable}
|
{beforeTable}
|
||||||
<EditableTable
|
<EditableTable
|
||||||
columns={columns}
|
columns={mergedColumns}
|
||||||
dataSource={files}
|
dataSource={files}
|
||||||
size={"small"}
|
size={'small'}
|
||||||
pagination={{
|
pagination={{
|
||||||
...pagination,
|
...pagination,
|
||||||
showSizeChanger: false,
|
showSizeChanger: false,
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import {Popconfirm, Button, Tooltip, Typography} from 'antd'
|
import { useEffect, useState } from 'react'
|
||||||
import { FileExcelOutlined } from '@ant-design/icons'
|
import { FileExcelOutlined } from '@ant-design/icons'
|
||||||
import { useEffect, useState } from "react"
|
import { Popconfirm, Button, Tooltip, Typography } from 'antd'
|
||||||
import {invokeWebApiWrapperAsync, download, formatBytes} from '../../components/factory'
|
|
||||||
import DocumentsTemplate from './DocumentsTemplate'
|
|
||||||
import LoaderPortal from '../../components/LoaderPortal'
|
|
||||||
import { Flex } from '../../components/Grid'
|
import { Flex } from '../../components/Grid'
|
||||||
|
import { Mark } from '../../components/Mark'
|
||||||
|
import { UserView } from '../../components/UserView'
|
||||||
|
import LoaderPortal from '../../components/LoaderPortal'
|
||||||
|
import { invokeWebApiWrapperAsync, download, formatBytes } from '../../components/factory'
|
||||||
import {DrillingProgramService, WellService} from '../../services/api'
|
import {DrillingProgramService, WellService} from '../../services/api'
|
||||||
import {Mark} from '../../components/Mark'
|
import DocumentsTemplate from './DocumentsTemplate'
|
||||||
import {UserView} from '../../components/UserView'
|
|
||||||
|
|
||||||
const idFileCategoryDrillingProgramItems = 13;
|
const idFileCategoryDrillingProgramItems = 13
|
||||||
const {Text} = Typography
|
const {Text} = Typography
|
||||||
|
|
||||||
export default function DrillingProgram({idWell}) {
|
export default function DrillingProgram({ idWell }) {
|
||||||
const [downloadButtonEnabled, selDownloadButtonEnabled] = useState(false)
|
const [downloadButtonEnabled, selDownloadButtonEnabled] = useState(false)
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
const [tooltip, setTooltip] = useState('нет файлов для формирования')
|
const [tooltip, setTooltip] = useState('нет файлов для формирования')
|
||||||
const [wellLabel, setWellLabel] = useState(`${idWell}`)
|
const [wellLabel, setWellLabel] = useState(`${idWell}`)
|
||||||
const [childKey, setChildKey] = useState();
|
const [childKey, setChildKey] = useState()
|
||||||
const [lastUpdatedFile, setLastUpdatedFile] = useState();
|
const [lastUpdatedFile, setLastUpdatedFile] = useState()
|
||||||
|
|
||||||
useEffect(() => invokeWebApiWrapperAsync(
|
useEffect(() => invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
@ -26,29 +26,31 @@ export default function DrillingProgram({idWell}) {
|
|||||||
setWellLabel(well.caption ?? `${idWell}`)
|
setWellLabel(well.caption ?? `${idWell}`)
|
||||||
},
|
},
|
||||||
setShowLoader,
|
setShowLoader,
|
||||||
`Не удалось загрузить название скважины "${idWell}"`
|
`Не удалось загрузить название скважины '${idWell}'`
|
||||||
), [idWell])
|
), [idWell])
|
||||||
|
|
||||||
const urlDownloadProgram =`/api/well/${idWell}/drillingProgram`
|
const urlDownloadProgram = `/api/well/${idWell}/drillingProgram`
|
||||||
|
|
||||||
const downloadProgram = () => invokeWebApiWrapperAsync(async()=>{
|
const downloadProgram = () => invokeWebApiWrapperAsync(
|
||||||
await download(urlDownloadProgram)
|
async () => await download(urlDownloadProgram),
|
||||||
},
|
setShowLoader,
|
||||||
setShowLoader,
|
'Не удалось загрузить программу бурения'
|
||||||
"Не удалось загрузить программу бурения")
|
)
|
||||||
|
|
||||||
const openProgramPreview = () => invokeWebApiWrapperAsync(async()=>{
|
const openProgramPreview = () => invokeWebApiWrapperAsync(
|
||||||
|
async() => {
|
||||||
const filWebUrl = await DrillingProgramService.getOrCreateSharedUrl(idWell)
|
const filWebUrl = await DrillingProgramService.getOrCreateSharedUrl(idWell)
|
||||||
if(filWebUrl && filWebUrl.length > 0)
|
if(filWebUrl && filWebUrl.length > 0)
|
||||||
window.open(filWebUrl, '_blank');
|
window.open(filWebUrl, '_blank')
|
||||||
else
|
else
|
||||||
throw new Error("Сервер вернул плохую ссылку")
|
throw new Error('Сервер вернул плохую ссылку')
|
||||||
},
|
},
|
||||||
setShowLoader,
|
setShowLoader,
|
||||||
"Не удалось создать быстрый просмотр программы")
|
'Не удалось создать быстрый просмотр программы'
|
||||||
|
)
|
||||||
|
|
||||||
const filesUpdated = (files) =>{
|
const filesUpdated = (files) => {
|
||||||
if(!files || files.length === 0){
|
if (!files || files.length === 0) {
|
||||||
setTooltip('Нет файлов для формирования программы')
|
setTooltip('Нет файлов для формирования программы')
|
||||||
selDownloadButtonEnabled(false)
|
selDownloadButtonEnabled(false)
|
||||||
return
|
return
|
||||||
@ -57,21 +59,20 @@ export default function DrillingProgram({idWell}) {
|
|||||||
const isAllFilesAreExcel = files.every(fileInfo => fileInfo?.name.toLowerCase().endsWith('.xlsx'))
|
const isAllFilesAreExcel = files.every(fileInfo => fileInfo?.name.toLowerCase().endsWith('.xlsx'))
|
||||||
const isAnyFileMarked = files.some(file => file?.fileMarks.some(m => m?.idMarkType === 1 && !m?.isDeleted))
|
const isAnyFileMarked = files.some(file => file?.fileMarks.some(m => m?.idMarkType === 1 && !m?.isDeleted))
|
||||||
|
|
||||||
if(isAllFilesAreExcel && isAnyFileMarked){
|
if (isAllFilesAreExcel && isAnyFileMarked) {
|
||||||
setTooltip('Программа доступна для скачивания')
|
setTooltip('Программа доступна для скачивания')
|
||||||
selDownloadButtonEnabled(true)
|
selDownloadButtonEnabled(true)
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
setTooltip('Список файлов содержит недопустимые типы файлов')
|
setTooltip('Список файлов содержит недопустимые типы файлов')
|
||||||
}
|
}
|
||||||
const last = files.reduce((pre, cur) => pre.uploadDate > cur.uploadDate ? pre : cur)
|
const last = files.reduce((pre, cur) => pre.uploadDate > cur.uploadDate ? pre : cur)
|
||||||
setLastUpdatedFile(last);
|
setLastUpdatedFile(last)
|
||||||
}
|
}
|
||||||
|
|
||||||
const customColumns = [
|
const customColumns = [
|
||||||
{
|
{
|
||||||
title: "Метки",
|
title: 'Метки',
|
||||||
key: "fileMarks",
|
key: 'fileMarks',
|
||||||
render: (_, record) => renderMarksColumn(record?.id, record?.fileMarks)
|
render: (_, record) => renderMarksColumn(record?.id, record?.fileMarks)
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -81,18 +82,20 @@ export default function DrillingProgram({idWell}) {
|
|||||||
if(validMarks?.length)
|
if(validMarks?.length)
|
||||||
return validMarks.map(mark => <Mark mark = {mark} onDelete={() => deleteMark(mark.id)}/>)
|
return validMarks.map(mark => <Mark mark = {mark} onDelete={() => deleteMark(mark.id)}/>)
|
||||||
|
|
||||||
return true &&
|
return (
|
||||||
<Popconfirm title="Согласовать файл?" onConfirm={() => addMarkToFile(idFile)}>
|
<Popconfirm title={'Согласовать файл?'} onConfirm={() => addMarkToFile(idFile)}>
|
||||||
<Button type="link">Согласовать</Button>
|
<Button type={'link'}>Согласовать</Button>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addMarkToFile = async (idFile) => {
|
const addMarkToFile = async (idFile) => {
|
||||||
const mark = {
|
const mark = {
|
||||||
idFile: idFile,
|
idFile: idFile,
|
||||||
idMarkType: 1,
|
idMarkType: 1,
|
||||||
isDeleted:false,
|
isDeleted: false,
|
||||||
comment: ''}
|
comment: '',
|
||||||
|
}
|
||||||
await DrillingProgramService.createFileMark(idWell, mark)
|
await DrillingProgramService.createFileMark(idWell, mark)
|
||||||
selDownloadButtonEnabled(true)
|
selDownloadButtonEnabled(true)
|
||||||
setChildKey(Date.now())
|
setChildKey(Date.now())
|
||||||
@ -103,51 +106,59 @@ export default function DrillingProgram({idWell}) {
|
|||||||
setChildKey(Date.now())
|
setChildKey(Date.now())
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadButton = <div>
|
const downloadButton = (
|
||||||
<span>Программа бурения</span>
|
<div>
|
||||||
<Flex>
|
<span>Программа бурения</span>
|
||||||
<Tooltip title={tooltip}>
|
<Flex>
|
||||||
<Button
|
<Tooltip title={tooltip}>
|
||||||
type="primary"
|
|
||||||
onClick={downloadProgram}
|
|
||||||
disabled={!downloadButtonEnabled}>
|
|
||||||
Сформировать и скачать
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title="Просмотреть через GoogleDrive">
|
|
||||||
<Popconfirm
|
|
||||||
title="Загрузить файл на GoogleDrive для просмотра?"
|
|
||||||
onConfirm={openProgramPreview}
|
|
||||||
disabled={!downloadButtonEnabled}>
|
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type={'primary'}
|
||||||
disabled={!downloadButtonEnabled}>
|
onClick={downloadProgram}
|
||||||
<FileExcelOutlined />
|
disabled={!downloadButtonEnabled}
|
||||||
Программа бурения {wellLabel}.xlsx
|
>
|
||||||
|
Сформировать и скачать
|
||||||
</Button>
|
</Button>
|
||||||
</Popconfirm>
|
</Tooltip>
|
||||||
</Tooltip>
|
<Tooltip title={'Просмотреть через GoogleDrive'}>
|
||||||
</Flex>
|
<Popconfirm
|
||||||
</div>
|
title={'Загрузить файл на GoogleDrive для просмотра?'}
|
||||||
|
onConfirm={openProgramPreview}
|
||||||
|
disabled={!downloadButtonEnabled}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type={'link'}
|
||||||
|
disabled={!downloadButtonEnabled}
|
||||||
|
>
|
||||||
|
<FileExcelOutlined />
|
||||||
|
Программа бурения {wellLabel}.xlsx
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
const lastUpdatedFileView = lastUpdatedFile &&
|
const lastUpdatedFileView = lastUpdatedFile &&
|
||||||
<Text>
|
<Text>
|
||||||
<b>Последнее изменние:</b>
|
<b>Последнее изменние:</b>
|
||||||
"{lastUpdatedFile.name}"
|
'{lastUpdatedFile.name}'
|
||||||
[{formatBytes(lastUpdatedFile.size)}]
|
[{formatBytes(lastUpdatedFile.size)}]
|
||||||
загружен: {new Date(lastUpdatedFile.uploadDate).toLocaleString()}
|
загружен: {new Date(lastUpdatedFile.uploadDate).toLocaleString()}
|
||||||
автор: <UserView user={lastUpdatedFile.author}/>
|
автор: <UserView user={lastUpdatedFile.author}/>
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
return(<LoaderPortal show={showLoader}>
|
return (
|
||||||
|
<LoaderPortal show={showLoader}>
|
||||||
<DocumentsTemplate
|
<DocumentsTemplate
|
||||||
beforeTable={lastUpdatedFileView}
|
beforeTable={lastUpdatedFileView}
|
||||||
idWell={idWell}
|
idWell={idWell}
|
||||||
idCategory={idFileCategoryDrillingProgramItems}
|
idCategory={idFileCategoryDrillingProgramItems}
|
||||||
accept='.xlsx'
|
accept={'.xlsx'}
|
||||||
headerChild={downloadButton}
|
headerChild={downloadButton}
|
||||||
onChange={filesUpdated}
|
onChange={filesUpdated}
|
||||||
customColumns = {customColumns}
|
customColumns = {customColumns}
|
||||||
key = {childKey}/>
|
key = {childKey}
|
||||||
</LoaderPortal>)
|
/>
|
||||||
|
</LoaderPortal>
|
||||||
|
)
|
||||||
}
|
}
|
@ -1,27 +1,68 @@
|
|||||||
import {Layout, Menu} from "antd";
|
import path from 'path'
|
||||||
import {Switch, useParams} from "react-router-dom";
|
import { memo } from 'react'
|
||||||
import {makeMenuItems, makeRouteItems} from './menuItems'
|
import { Layout, Menu } from 'antd'
|
||||||
|
import { FolderOutlined } from '@ant-design/icons'
|
||||||
|
import { Switch, useParams, Link, Route } from 'react-router-dom'
|
||||||
|
import { PrivateMenuItem } from '../../components/Private'
|
||||||
|
import { isInRole } from '../../utils/PermissionService'
|
||||||
|
import DocumentsTemplate from './DocumentsTemplate'
|
||||||
|
|
||||||
const { Content } = Layout
|
const { Content } = Layout
|
||||||
|
|
||||||
export default function MenuDocuments({idWell}) {
|
export const documentCategories = [
|
||||||
let {category} = useParams()
|
{ id: 1, key: 'fluidService', title: 'Растворный сервис' },
|
||||||
|
{ id: 2, key: 'cementing', title: 'Цементирование' },
|
||||||
|
{ id: 3, key: 'nnb', title: 'ННБ' },
|
||||||
|
{ id: 4, key: 'gti', title: 'ГТИ' },
|
||||||
|
{ id: 5, key: 'documentsForWell', title: 'Документы по скважине' },
|
||||||
|
{ id: 6, key: 'supervisor', title: 'Супервайзер' },
|
||||||
|
{ id: 7, key: 'master', title: 'Мастер' },
|
||||||
|
{ id: 8, key: 'toolService', title: 'Долотный сервис' },
|
||||||
|
{ id: 9, key: 'drillService', title: 'Буровой подрядчик' },
|
||||||
|
{ id: 9, key: 'closingService', title: 'Сервис по заканчиванию скважины' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const getUserCategories = () => documentCategories.filter(cat => isInRole(cat.roles))
|
||||||
|
|
||||||
|
export const makeMenuItems = (root, cats) => {
|
||||||
|
const categories = cats ?? getUserCategories()
|
||||||
|
return categories.map(category => (
|
||||||
|
<PrivateMenuItem className={'ant-menu-item'} key={`${category.key}`} icon={<FolderOutlined/>}>
|
||||||
|
<Link to={{ pathname: `${root}/${category.key}` }}>{category.title}</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MenuDocuments = memo(({ idWell }) => {
|
||||||
|
const { category } = useParams()
|
||||||
const rootPath = `/well/${idWell}`
|
const rootPath = `/well/${idWell}`
|
||||||
|
|
||||||
return(<>
|
const root = path.join(rootPath, '/document')
|
||||||
<Menu
|
const categories = getUserCategories()
|
||||||
mode="horizontal"
|
|
||||||
selectable={true}
|
return (
|
||||||
className="well_menu"
|
<>
|
||||||
selectedKeys={[category]}>
|
<Menu
|
||||||
{makeMenuItems(rootPath)}
|
mode={'horizontal'}
|
||||||
</Menu>
|
selectable={true}
|
||||||
<Layout>
|
className={'well_menu'}
|
||||||
<Content className="site-layout-background">
|
selectedKeys={[category]}
|
||||||
|
>
|
||||||
|
{makeMenuItems(root, categories)}
|
||||||
|
</Menu>
|
||||||
|
<Layout>
|
||||||
|
<Content className={'site-layout-background'}>
|
||||||
<Switch>
|
<Switch>
|
||||||
{makeRouteItems(rootPath, idWell)}
|
{categories.map(category => (
|
||||||
|
<Route path={`${root}/${category.key}`} key={`${category.key}`}>
|
||||||
|
<DocumentsTemplate idCategory={category.id} idWell={idWell}/>
|
||||||
|
</Route>
|
||||||
|
))}
|
||||||
</Switch>
|
</Switch>
|
||||||
</Content>
|
</Content>
|
||||||
</Layout>
|
</Layout>
|
||||||
</>)
|
</>
|
||||||
}
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default MenuDocuments
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
import path from 'path'
|
|
||||||
import { FolderOutlined } from '@ant-design/icons'
|
|
||||||
import { Link, Route } from 'react-router-dom'
|
|
||||||
import { PrivateMenuItem } from '../../components/Private'
|
|
||||||
import { getUserRoles, isInRole } from "../../utils/PermissionService";
|
|
||||||
import DocumentsTemplate from './DocumentsTemplate'
|
|
||||||
|
|
||||||
export const documentCategories = [
|
|
||||||
{ id: 1, key: 'fluidService', title: 'Растворный сервис' },
|
|
||||||
{ id: 2, key: 'cementing', title: 'Цементирование' },
|
|
||||||
{ id: 3, key: 'nnb', title: 'ННБ' },
|
|
||||||
{ id: 4, key: 'gti', title: 'ГТИ' },
|
|
||||||
{ id: 5, key: 'documentsForWell', title: 'Документы по скважине' },
|
|
||||||
{ id: 6, key: 'supervisor', title: 'Супервайзер' },
|
|
||||||
{ id: 7, key: 'master', title: 'Мастер' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const makeMenuItem = (keyValue, rootPath, title, other) => (
|
|
||||||
<PrivateMenuItem className={'ant-menu-item'} key={`${keyValue}`} {...other}>
|
|
||||||
<Link to={{pathname: `${rootPath}/${keyValue}`}}>{title}</Link>
|
|
||||||
</PrivateMenuItem>
|
|
||||||
)
|
|
||||||
|
|
||||||
const makeRouteItem = (keyValue, rootPath, other) => (
|
|
||||||
<Route
|
|
||||||
path={`${rootPath}/${keyValue}`}
|
|
||||||
key={`${keyValue}`}
|
|
||||||
>
|
|
||||||
<DocumentsTemplate {...other}/>
|
|
||||||
</Route>
|
|
||||||
)
|
|
||||||
|
|
||||||
const getCategoriesByUserRole = (role) => documentCategories.filter(cat => isInRole(cat.roles))
|
|
||||||
|
|
||||||
export const makeMenuItems = (rootPath) => {
|
|
||||||
const root = path.join(rootPath, '/document')
|
|
||||||
const categories = getCategoriesByUserRole(getUserRoles())
|
|
||||||
return categories.map(category =>
|
|
||||||
makeMenuItem(category.key, root, category.title, {icon:<FolderOutlined/>}))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const makeRouteItems = (rootPath, idWell) => {
|
|
||||||
const root = path.join(rootPath, '/document')
|
|
||||||
const categories = getCategoriesByUserRole(getUserRoles())
|
|
||||||
const routes = categories.map(category => makeRouteItem(category.key, root, {
|
|
||||||
idCategory: category.id,
|
|
||||||
idWell: idWell
|
|
||||||
}))
|
|
||||||
return routes
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ import { Select, Modal, Input, InputNumber } from 'antd'
|
|||||||
import { SetpointsService } from '../../services/api'
|
import { SetpointsService } from '../../services/api'
|
||||||
import LoaderPortal from '../../components/LoaderPortal'
|
import LoaderPortal from '../../components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
||||||
import { makeNumericRender, EditableTable, makeNumericInput } from '../../components/Table'
|
import { makeNumericRender, EditableTable } from '../../components/Table'
|
||||||
import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker'
|
import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker'
|
||||||
import { Grid, GridItem } from '../../components/Grid'
|
import { Grid, GridItem } from '../../components/Grid'
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ export const SetpointSender = ({ idWell, onClose, visible, setpointNames }) => {
|
|||||||
|
|
||||||
const onModalOk = () => invokeWebApiWrapperAsync(
|
const onModalOk = () => invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
|
// eslint-disable-next-line no-sequences
|
||||||
const setpointsObject = setpoints.reduce((obj, sp) => (obj[sp.name] = sp.value, obj), {})
|
const setpointsObject = setpoints.reduce((obj, sp) => (obj[sp.name] = sp.value, obj), {})
|
||||||
const request = {
|
const request = {
|
||||||
uploadDate: new Date(),
|
uploadDate: new Date(),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Layout, Menu } from "antd";
|
import { Layout, Menu } from 'antd'
|
||||||
import {
|
import {
|
||||||
FolderOutlined,
|
FolderOutlined,
|
||||||
FundViewOutlined,
|
FundViewOutlined,
|
||||||
@ -6,112 +6,111 @@ import {
|
|||||||
FilePdfOutlined,
|
FilePdfOutlined,
|
||||||
DatabaseOutlined,
|
DatabaseOutlined,
|
||||||
ExperimentOutlined,
|
ExperimentOutlined,
|
||||||
//FundProjectionScreenOutlined
|
FundProjectionScreenOutlined,
|
||||||
} from "@ant-design/icons";
|
} from '@ant-design/icons'
|
||||||
import { Link, Redirect, Route, Switch, useParams } from "react-router-dom";
|
import { Link, Redirect, Route, Switch, useParams } from 'react-router-dom'
|
||||||
import TelemetryView from "./TelemetryView";
|
import { PrivateMenuItem } from '../components/Private'
|
||||||
import Messages from "./Messages";
|
import TelemetryView from './TelemetryView'
|
||||||
import Report from "./Report";
|
import Messages from './Messages'
|
||||||
import Archive from "./Archive";
|
import Report from './Report'
|
||||||
import Documents from "./Documents";
|
import Archive from './Archive'
|
||||||
import Measure from "./Measure";
|
import Documents from './Documents'
|
||||||
import { makeMenuItems } from "./Documents/menuItems";
|
import Measure from './Measure'
|
||||||
import WellOperations from "./WellOperations";
|
import WellOperations from './WellOperations'
|
||||||
import DrillingProgram from "./Documents/DrillingProgram";
|
import TelemetryAnalysis from './TelemetryAnalysis'
|
||||||
import TelemetryAnalysis from "./TelemetryAnalysis"
|
import { makeMenuItems } from './Documents/'
|
||||||
import {PrivateMenuItem} from '../components/Private'
|
import DrillingProgram from './Documents/DrillingProgram'
|
||||||
|
|
||||||
const { Content } = Layout;
|
const { Content } = Layout
|
||||||
|
|
||||||
export default function Well() {
|
export default function Well() {
|
||||||
let { idWell, tab } = useParams();
|
const { idWell, tab } = useParams()
|
||||||
const rootPath = `/well/${idWell}`;
|
const rootPath = `/well/${idWell}`
|
||||||
|
|
||||||
const { SubMenu } = Menu;
|
const { SubMenu } = Menu
|
||||||
|
|
||||||
return <Layout>
|
return (
|
||||||
<Menu
|
<Layout>
|
||||||
mode="horizontal"
|
<Menu
|
||||||
|
mode={'horizontal'}
|
||||||
|
selectable={true}
|
||||||
|
selectedKeys={[tab]}
|
||||||
|
className={'well_menu'}
|
||||||
|
>
|
||||||
|
<PrivateMenuItem key={'telemetry'} icon={<FundViewOutlined />}>
|
||||||
|
<Link to={`${rootPath}/telemetry`}>Мониторинг</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
<PrivateMenuItem key={'message'} icon={<AlertOutlined/>}>
|
||||||
|
<Link to={`${rootPath}/message`}>Сообщения</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
<PrivateMenuItem key={'report'} icon={<FilePdfOutlined />}>
|
||||||
|
<Link to={`${rootPath}/report`}>Рапорт</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
<PrivateMenuItem key={'operations'} icon={<FolderOutlined />}>
|
||||||
|
<Link to={`${rootPath}/operations`}>Операции по скважине</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
<PrivateMenuItem key={'archive'} icon={<DatabaseOutlined />}>
|
||||||
|
<Link to={`${rootPath}/archive`}>Архив</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
<PrivateMenuItem key={'telemetryAnalysis'} icon={<FundProjectionScreenOutlined />} roles={'admin'}>
|
||||||
|
<Link to={`${rootPath}/telemetryAnalysis/depthToDay`}>Операции по телеметрии</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
|
<SubMenu
|
||||||
|
key={'document'}
|
||||||
|
title={
|
||||||
|
<Link to={`${rootPath}/document/fluidService`} className={'linkDocuments'}>
|
||||||
|
Документы
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
icon={<FolderOutlined />}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
selectedKeys={[tab]}
|
|
||||||
className="well_menu"
|
|
||||||
>
|
>
|
||||||
<PrivateMenuItem key="telemetry" icon={<FundViewOutlined />}>
|
{makeMenuItems(rootPath)}
|
||||||
<Link to={`${rootPath}/telemetry`}>Мониторинг</Link>
|
</SubMenu>
|
||||||
</PrivateMenuItem>
|
<PrivateMenuItem key={'measure'} icon={<ExperimentOutlined />}>
|
||||||
<PrivateMenuItem key="message" icon={<AlertOutlined/>} roles={[]}>
|
<Link to={`${rootPath}/measure`}>Измерения</Link>
|
||||||
<Link to={`${rootPath}/message`}>Сообщения</Link>
|
</PrivateMenuItem>
|
||||||
</PrivateMenuItem>
|
<PrivateMenuItem key={'drillingProgram'} icon={<FolderOutlined />}>
|
||||||
<PrivateMenuItem key="report" icon={<FilePdfOutlined />}>
|
<Link to={`${rootPath}/drillingProgram`}>Программа бурения</Link>
|
||||||
<Link to={`${rootPath}/report`}>Рапорт</Link>
|
</PrivateMenuItem>
|
||||||
</PrivateMenuItem>
|
</Menu>
|
||||||
<PrivateMenuItem key="operations" icon={<FolderOutlined />}>
|
|
||||||
<Link to={`${rootPath}/operations`}>Операции по скважине</Link>
|
|
||||||
</PrivateMenuItem>
|
|
||||||
<PrivateMenuItem key="archive" icon={<DatabaseOutlined />}>
|
|
||||||
<Link to={`${rootPath}/archive`}>Архив</Link>
|
|
||||||
</PrivateMenuItem>
|
|
||||||
{/* <PrivateMenuItem key="telemetryAnalysis" icon={<FundProjectionScreenOutlined />}>
|
|
||||||
<Link to={`${rootPath}/telemetryAnalysis/depthToDay`}>Операции по телеметрии</Link>
|
|
||||||
</PrivateMenuItem> */}
|
|
||||||
<SubMenu
|
|
||||||
key="document"
|
|
||||||
title={
|
|
||||||
<Link
|
|
||||||
to={`${rootPath}/document/fluidService`}
|
|
||||||
className="linkDocuments"
|
|
||||||
>
|
|
||||||
Документы
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
icon={<FolderOutlined />}
|
|
||||||
selectable={true}
|
|
||||||
>
|
|
||||||
{makeMenuItems(rootPath)}
|
|
||||||
</SubMenu>
|
|
||||||
<PrivateMenuItem key="measure" icon={<ExperimentOutlined />}>
|
|
||||||
<Link to={`${rootPath}/measure`}>Измерения</Link>
|
|
||||||
</PrivateMenuItem>
|
|
||||||
<PrivateMenuItem key="drillingProgram" icon={<FolderOutlined />}>
|
|
||||||
<Link to={`${rootPath}/drillingProgram`}>Программа бурения</Link>
|
|
||||||
</PrivateMenuItem>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<Content className="site-layout-background">
|
<Content className={'site-layout-background'}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/well/:idWell/telemetry">
|
<Route path={'/well/:idWell/telemetry'}>
|
||||||
<TelemetryView idWell={idWell} />
|
<TelemetryView idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:idWell/message">
|
<Route path={'/well/:idWell/message'}>
|
||||||
<Messages idWell={idWell} />
|
<Messages idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:idWell/report">
|
<Route path={'/well/:idWell/report'}>
|
||||||
<Report idWell={idWell} />
|
<Report idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:idWell/operations/:tab?">
|
<Route path={'/well/:idWell/operations/:tab?'}>
|
||||||
<WellOperations idWell={idWell} />
|
<WellOperations idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:idWell/archive">
|
<Route path={'/well/:idWell/archive'}>
|
||||||
<Archive idWell={idWell} />
|
<Archive idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:idWell/telemetryAnalysis/:tab">
|
<Route path={'/well/:idWell/telemetryAnalysis/:tab'}>
|
||||||
<TelemetryAnalysis idWell={idWell} />
|
<TelemetryAnalysis idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:idWell/document/:category">
|
<Route path={'/well/:idWell/document/:category'}>
|
||||||
<Documents idWell={idWell} />
|
<Documents idWell={idWell} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:id/measure">
|
<Route path={'/well/:id/measure'}>
|
||||||
<Measure idWell={idWell}/>
|
<Measure idWell={idWell}/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/well/:id/drillingProgram">
|
<Route path={'/well/:id/drillingProgram'}>
|
||||||
<DrillingProgram idWell={idWell}/>
|
<DrillingProgram idWell={idWell}/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/">
|
<Route path={'/'}>
|
||||||
<Redirect to={`${rootPath}/telemetry`} />
|
<Redirect to={`${rootPath}/telemetry`} />
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Content>
|
</Content>
|
||||||
</Layout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user