forked from ddrilling/asb_cloud_front
Закончена первая версия Дела скважины
This commit is contained in:
parent
6c52a091c9
commit
664e3aa57a
@ -3,25 +3,14 @@ import { Empty, Timeline } from 'antd'
|
||||
import moment from 'moment'
|
||||
|
||||
import { useWell } from '@asb/context'
|
||||
import { UserView } from '@components/views'
|
||||
import DownloadLink from '@components/DownloadLink'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
// import { makeColumn, makeDateColumn, Table } from '@components/Table'
|
||||
import { WellFinalDocumentsService } from '@api'
|
||||
import { formatDate } from '@utils'
|
||||
import { UserView } from '@asb/components/views'
|
||||
|
||||
// const columns = [
|
||||
// makeColumn('Файл', 'file', {
|
||||
// render: (file) => (
|
||||
// <DownloadLink file={file} />
|
||||
// ),
|
||||
// }),
|
||||
// makeDateColumn('Дата загрузки', 'date', undefined, undefined, {
|
||||
// defaultSortOrder: 'descend',
|
||||
// }),
|
||||
// ]
|
||||
|
||||
export const HistoryTable = memo(({ users, category }) => {
|
||||
export const HistoryTable = memo(({ category }) => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [files, setFiles] = useState([])
|
||||
|
||||
@ -30,26 +19,29 @@ export const HistoryTable = memo(({ users, category }) => {
|
||||
useEffect(() => {
|
||||
invokeWebApiWrapperAsync(
|
||||
async () => {
|
||||
const files = [{ uploadDate: moment().format(), id: 0, idWell: 0 }]
|
||||
const result = await WellFinalDocumentsService.getFilesHistoryByIdCategory(well.id, category.idCategory)
|
||||
if (!result) return
|
||||
const files = result.file
|
||||
files.sort((a, b) => moment(a.uploadDate) - moment(b.uploadDate))
|
||||
const fileSource = files.map((file) => ({
|
||||
file,
|
||||
date: file.uploadDate,
|
||||
user: users.find(({ id }) => id === file.idAuthor) ?? null,
|
||||
user: file.author,
|
||||
}))
|
||||
setFiles(fileSource) // Получаем список файлов и записываем в state
|
||||
setFiles(fileSource)
|
||||
},
|
||||
setIsLoading,
|
||||
`Не удалось загрузить историю файлов категории "${category.caption}"`,
|
||||
`Не удалось загрузить историю файлов категории "${category.nameCategory}"`,
|
||||
{ actionName: `Загрузка истории файлов категории "${category.nameCategory}"`, well }
|
||||
)
|
||||
}, [well, category])
|
||||
|
||||
return (
|
||||
<LoaderPortal show={isLoading}>
|
||||
{files.length > 0 ? (
|
||||
<Timeline reverse style={{ marginLeft: 20 }}>
|
||||
<Timeline reverse style={{ marginLeft: 50, marginTop: 20 }}>
|
||||
{files.map(({ date, user, file }) => (
|
||||
<Timeline.Item>
|
||||
<Timeline.Item key={date}>
|
||||
{formatDate(date)}
|
||||
<UserView user={user} style={{ marginLeft: 10 }} />
|
||||
<DownloadLink file={file} />
|
||||
@ -57,17 +49,10 @@ export const HistoryTable = memo(({ users, category }) => {
|
||||
))}
|
||||
</Timeline>
|
||||
) : (
|
||||
<Empty />
|
||||
<Empty description={'Нет данных о версиях файлов'} />
|
||||
)}
|
||||
{/* <Table
|
||||
bordered
|
||||
size={'small'}
|
||||
dataSource={files}
|
||||
columns={columns}
|
||||
/> */}
|
||||
</LoaderPortal>
|
||||
)
|
||||
})
|
||||
|
||||
export default HistoryTable
|
||||
|
||||
|
@ -1,20 +1,161 @@
|
||||
import { memo, useCallback, useState } from 'react'
|
||||
import { Modal, Transfer } from 'antd'
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { AutoComplete, List, Modal, Tooltip, Transfer } from 'antd'
|
||||
|
||||
import { useWell } from '@asb/context'
|
||||
import { UserView } from '@components/views'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { WellFinalDocumentsService } from '@api'
|
||||
import { arrayOrDefault } from '@utils'
|
||||
|
||||
export const WellCaseEditor = memo(({ show, onClose }) => {
|
||||
const [users, setUsers] = useState([])
|
||||
import '@styles/well_case.less'
|
||||
|
||||
const filterCategoriesByText = (text) => (cat) =>
|
||||
!text || !!cat?.nameCategory?.toLowerCase().includes(text.toLowerCase())
|
||||
|
||||
const filterUserByText = (text, user) =>
|
||||
!text || (user && `${user.login} ${user.email} ${user.surname} ${user.name} ${user.patronymic}`.toLowerCase().includes(text.toLowerCase()))
|
||||
|
||||
export const WellCaseEditor = memo(({ categories: currentCategories, show, onClose }) => {
|
||||
const [users, setUsersDataSource] = useState([])
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [categories, setCategories] = useState([])
|
||||
const [availableCategories, setAvailableCategories] = useState([])
|
||||
const [catSearchText, setCatSearchText] = useState(null)
|
||||
const [selectedCatId, setSelectedCatId] = useState(null)
|
||||
|
||||
const [well] = useWell()
|
||||
|
||||
const unusedCategories = useMemo(() => availableCategories.filter(({ id }) => !categories.find((cat) => cat.idCategory === id)), [categories, availableCategories])
|
||||
|
||||
const catOptions = useMemo(() => {
|
||||
return unusedCategories
|
||||
.filter(filterCategoriesByText(catSearchText))
|
||||
.map((cat) => ({ label: cat.name, value: cat.name, id: cat.id }))
|
||||
}, [catSearchText, unusedCategories])
|
||||
|
||||
const onModalOk = useCallback(() => {
|
||||
onClose(true)
|
||||
invokeWebApiWrapperAsync(
|
||||
async () => {
|
||||
await WellFinalDocumentsService.updateRange(well.id, categories)
|
||||
onClose?.(true)
|
||||
},
|
||||
setIsLoading,
|
||||
'Не удалось изменить ответственных',
|
||||
{ actionName: 'Изменение ответственных', well }
|
||||
)
|
||||
}, [onClose, well, categories])
|
||||
|
||||
const onModalCancel = useCallback(() => onClose?.(false), [onClose])
|
||||
|
||||
const onAddCategory = useCallback((name, cat) => {
|
||||
setCategories((prev) => [...prev, { idCategory: cat.id, nameCategory: name, publishers: [] }])
|
||||
}, [])
|
||||
|
||||
const categoryRender = useCallback((item) => {
|
||||
const hasPublishers = item.idsPublishers?.length > 0
|
||||
const selected = selectedCatId === item.idCategory
|
||||
|
||||
return (
|
||||
<List.Item
|
||||
className={`category-list-item ${!hasPublishers ? 'empty' : ''} ${selected ? 'active' : ''}`}
|
||||
onClick={() => setSelectedCatId(item.idCategory)}
|
||||
>
|
||||
{hasPublishers ? (item.nameCategory) : (
|
||||
<Tooltip title={'Категория будет скрыта, так как не назначены ответственные'}>
|
||||
{item.nameCategory}
|
||||
</Tooltip>
|
||||
)}
|
||||
</List.Item>
|
||||
)
|
||||
}, [selectedCatId])
|
||||
|
||||
const onPublishersChange = useCallback((selectedPublishers) => {
|
||||
setCategories((prev) => {
|
||||
const cats = [...prev]
|
||||
const idx = cats.findIndex((cat) => cat.idCategory === selectedCatId)
|
||||
cats[idx].idsPublishers = selectedPublishers
|
||||
return cats
|
||||
})
|
||||
}, [selectedCatId])
|
||||
|
||||
useEffect(() => {
|
||||
const cats = currentCategories?.map((cat) => ({
|
||||
idCategory: cat.idCategory,
|
||||
nameCategory: cat.nameCategory,
|
||||
idsPublishers: cat.publishers.map((user) => user.id),
|
||||
}))
|
||||
setCategories(cats ?? [])
|
||||
}, [currentCategories])
|
||||
|
||||
useEffect(() => {
|
||||
invokeWebApiWrapperAsync(
|
||||
async () => {
|
||||
const users = arrayOrDefault(await WellFinalDocumentsService.getAvailableUsers(well.id))
|
||||
const usersDataSource = users.map((user) => ({ key: user.id, ...user }))
|
||||
setUsersDataSource(usersDataSource)
|
||||
},
|
||||
setIsLoading,
|
||||
'Не удалось загрузить список доступных публикаторов',
|
||||
{ actionName: 'Загрузка списка доступных публикаторов', well }
|
||||
)
|
||||
}, [well])
|
||||
|
||||
useEffect(() => {
|
||||
invokeWebApiWrapperAsync(
|
||||
async () => {
|
||||
const categories = arrayOrDefault(await WellFinalDocumentsService.getWellCaseCategories())
|
||||
setAvailableCategories(categories)
|
||||
},
|
||||
setIsLoading,
|
||||
'Не удалось загрузить список доступных категорий',
|
||||
{ actionName: 'Загрузка списка доступных категорий' }
|
||||
)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Modal visible={show} onCancel={() => onClose(false)} onOk={onModalOk}>
|
||||
<Transfer />
|
||||
<Modal
|
||||
centered
|
||||
width={1000}
|
||||
visible={show}
|
||||
onOk={onModalOk}
|
||||
onCancel={onModalCancel}
|
||||
okText={'Сохранить'}
|
||||
title={'Редактирование ответственных за категории'}
|
||||
>
|
||||
<LoaderPortal show={isLoading} style={{ width: '100%', height: '100%' }}>
|
||||
<div className={'well-case-editor'}>
|
||||
<div className={'category-list'}>
|
||||
<AutoComplete
|
||||
options={catOptions}
|
||||
onSearch={(searchText) => setCatSearchText(searchText)}
|
||||
onSelect={onAddCategory}
|
||||
placeholder={'Впишите категорию для добавления'}
|
||||
/>
|
||||
<List
|
||||
bordered
|
||||
size={'small'}
|
||||
style={{ flexGrow: 1 }}
|
||||
itemLayout={'horizontal'}
|
||||
dataSource={categories}
|
||||
renderItem={categoryRender}
|
||||
/>
|
||||
</div>
|
||||
<Transfer
|
||||
showSearch
|
||||
dataSource={users}
|
||||
disabled={!selectedCatId}
|
||||
listStyle={{ width: 300, height: '100%' }}
|
||||
titles={['Пользователи', 'Публикаторы']}
|
||||
onChange={onPublishersChange}
|
||||
filterOption={filterUserByText}
|
||||
targetKeys={categories.find((cat) => cat.idCategory === selectedCatId)?.idsPublishers ?? []}
|
||||
render={(item) => (
|
||||
<UserView user={item} />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</LoaderPortal>
|
||||
</Modal>
|
||||
)
|
||||
})
|
||||
|
@ -7,64 +7,77 @@ import DownloadLink from '@components/DownloadLink'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||
import { makeColumn, makeDateColumn, makeTextColumn, Table } from '@components/Table'
|
||||
import { delay, wrapPrivateComponent } from '@utils'
|
||||
import { WellFinalDocumentsService } from '@api'
|
||||
import { MimeTypes, wrapPrivateComponent } from '@utils'
|
||||
|
||||
import WellCaseEditor from './WellCaseEditor'
|
||||
import { HistoryTable } from './HistoryTable'
|
||||
import UploadForm from '@asb/components/UploadForm'
|
||||
|
||||
const columns = [
|
||||
makeTextColumn('Категория', 'caption'),
|
||||
makeColumn('Файл', 'file', {
|
||||
render: (file) => file ? (
|
||||
<DownloadLink file={file} />
|
||||
) : (
|
||||
<span>Файл не загружен</span>
|
||||
),
|
||||
}),
|
||||
makeDateColumn('Дата загрузки', 'uploadDate'),
|
||||
makeColumn('Ответственные', 'responsible', {
|
||||
render: (responsible) => responsible.map((user) => (
|
||||
<UserView user={user} />
|
||||
)),
|
||||
}),
|
||||
]
|
||||
const expandable = {
|
||||
expandedRowRender: (category) => (
|
||||
<HistoryTable category={category} />
|
||||
)
|
||||
}
|
||||
|
||||
const WellCase = memo(() => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [categories, setCategories] = useState([])
|
||||
const [canEdit, setCanEdit] = useState(false)
|
||||
const [showEdit, setShowEdit] = useState(false)
|
||||
const [users, setUsers] = useState([])
|
||||
|
||||
const [well] = useWell()
|
||||
|
||||
const updateTable = useCallback(() => {
|
||||
invokeWebApiWrapperAsync(
|
||||
async () => {
|
||||
await delay(1000)
|
||||
const categories = [{ responsible: [{}] }]
|
||||
const { permissionToSetPubliher, wellFinalDocuments } = await WellFinalDocumentsService.get(well.id)
|
||||
|
||||
setCanEdit(true)
|
||||
const showingCategories = categories.filter((cat) => cat.responsible && cat.responsible?.length > 0)
|
||||
setCategories(showingCategories)
|
||||
setCategories(wellFinalDocuments.map((cat) => ({ ...cat, uploadDate: cat.file?.uploadDate })))
|
||||
setCanEdit(permissionToSetPubliher)
|
||||
},
|
||||
setIsLoading,
|
||||
'Не удалось загрузить список категорий',
|
||||
{ actionName: 'Загрузка списка категорий', well }
|
||||
)
|
||||
}, [well])
|
||||
|
||||
const columns = useMemo(() => [
|
||||
makeTextColumn('Категория', 'nameCategory'),
|
||||
makeColumn('Файл', 'file', {
|
||||
render: (file, category) => (
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
|
||||
{file ? (
|
||||
<DownloadLink file={file} />
|
||||
) : (
|
||||
<span style={{ marginLeft: 15 }}>Файл не загружен</span>
|
||||
)}
|
||||
|
||||
{category.permissionToUpload && (
|
||||
<UploadForm
|
||||
url={`/api/WellFinalDocuments/${well.id}?idCategory=${category.idCategory}`}
|
||||
onUploadStart={() => setIsLoading(true)}
|
||||
onUploadComplete={updateTable}
|
||||
onUploadError={() => setIsLoading(false)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
}),
|
||||
makeDateColumn('Дата загрузки', 'uploadDate'),
|
||||
makeColumn('Ответственные', 'publishers', {
|
||||
render: (publishers) => publishers?.map((user) => (
|
||||
<UserView user={user} />
|
||||
)),
|
||||
}),
|
||||
], [well, updateTable])
|
||||
|
||||
const onEditClose = useCallback((changed = false) => {
|
||||
setShowEdit(false)
|
||||
if (changed) updateTable()
|
||||
}, [updateTable])
|
||||
|
||||
const expandable = useMemo(() => ({
|
||||
expandedRowRender: (category) => (
|
||||
<HistoryTable users={users} category={category} />
|
||||
)
|
||||
}), [users])
|
||||
|
||||
useEffect(() => updateTable(), [updateTable])
|
||||
useEffect(updateTable, [updateTable])
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -80,7 +93,7 @@ const WellCase = memo(() => {
|
||||
expandable={expandable}
|
||||
/>
|
||||
</LoaderPortal>
|
||||
<WellCaseEditor users={users} show={showEdit} onClose={onEditClose} />
|
||||
<WellCaseEditor categories={categories} show={showEdit} onClose={onEditClose} />
|
||||
</>
|
||||
)
|
||||
})
|
||||
@ -89,4 +102,5 @@ export default wrapPrivateComponent(WellCase, {
|
||||
title: 'Дело скважины',
|
||||
route: 'well_case',
|
||||
requirements: [],
|
||||
// requirements: ['WellFinalDocuments.get'],
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user