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 moment from 'moment'
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
import { useWell } from '@asb/context'
|
||||||
|
import { UserView } from '@components/views'
|
||||||
import DownloadLink from '@components/DownloadLink'
|
import DownloadLink from '@components/DownloadLink'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
// import { makeColumn, makeDateColumn, Table } from '@components/Table'
|
import { WellFinalDocumentsService } from '@api'
|
||||||
import { formatDate } from '@utils'
|
import { formatDate } from '@utils'
|
||||||
import { UserView } from '@asb/components/views'
|
|
||||||
|
|
||||||
// const columns = [
|
export const HistoryTable = memo(({ category }) => {
|
||||||
// makeColumn('Файл', 'file', {
|
|
||||||
// render: (file) => (
|
|
||||||
// <DownloadLink file={file} />
|
|
||||||
// ),
|
|
||||||
// }),
|
|
||||||
// makeDateColumn('Дата загрузки', 'date', undefined, undefined, {
|
|
||||||
// defaultSortOrder: 'descend',
|
|
||||||
// }),
|
|
||||||
// ]
|
|
||||||
|
|
||||||
export const HistoryTable = memo(({ users, category }) => {
|
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [files, setFiles] = useState([])
|
const [files, setFiles] = useState([])
|
||||||
|
|
||||||
@ -30,26 +19,29 @@ export const HistoryTable = memo(({ users, category }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
invokeWebApiWrapperAsync(
|
invokeWebApiWrapperAsync(
|
||||||
async () => {
|
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))
|
files.sort((a, b) => moment(a.uploadDate) - moment(b.uploadDate))
|
||||||
const fileSource = files.map((file) => ({
|
const fileSource = files.map((file) => ({
|
||||||
file,
|
file,
|
||||||
date: file.uploadDate,
|
date: file.uploadDate,
|
||||||
user: users.find(({ id }) => id === file.idAuthor) ?? null,
|
user: file.author,
|
||||||
}))
|
}))
|
||||||
setFiles(fileSource) // Получаем список файлов и записываем в state
|
setFiles(fileSource)
|
||||||
},
|
},
|
||||||
setIsLoading,
|
setIsLoading,
|
||||||
`Не удалось загрузить историю файлов категории "${category.caption}"`,
|
`Не удалось загрузить историю файлов категории "${category.nameCategory}"`,
|
||||||
|
{ actionName: `Загрузка истории файлов категории "${category.nameCategory}"`, well }
|
||||||
)
|
)
|
||||||
}, [well, category])
|
}, [well, category])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal show={isLoading}>
|
<LoaderPortal show={isLoading}>
|
||||||
{files.length > 0 ? (
|
{files.length > 0 ? (
|
||||||
<Timeline reverse style={{ marginLeft: 20 }}>
|
<Timeline reverse style={{ marginLeft: 50, marginTop: 20 }}>
|
||||||
{files.map(({ date, user, file }) => (
|
{files.map(({ date, user, file }) => (
|
||||||
<Timeline.Item>
|
<Timeline.Item key={date}>
|
||||||
{formatDate(date)}
|
{formatDate(date)}
|
||||||
<UserView user={user} style={{ marginLeft: 10 }} />
|
<UserView user={user} style={{ marginLeft: 10 }} />
|
||||||
<DownloadLink file={file} />
|
<DownloadLink file={file} />
|
||||||
@ -57,17 +49,10 @@ export const HistoryTable = memo(({ users, category }) => {
|
|||||||
))}
|
))}
|
||||||
</Timeline>
|
</Timeline>
|
||||||
) : (
|
) : (
|
||||||
<Empty />
|
<Empty description={'Нет данных о версиях файлов'} />
|
||||||
)}
|
)}
|
||||||
{/* <Table
|
|
||||||
bordered
|
|
||||||
size={'small'}
|
|
||||||
dataSource={files}
|
|
||||||
columns={columns}
|
|
||||||
/> */}
|
|
||||||
</LoaderPortal>
|
</LoaderPortal>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
export default HistoryTable
|
export default HistoryTable
|
||||||
|
|
||||||
|
@ -1,20 +1,161 @@
|
|||||||
import { memo, useCallback, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { Modal, Transfer } from 'antd'
|
import { AutoComplete, List, Modal, Tooltip, Transfer } from 'antd'
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
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 }) => {
|
import '@styles/well_case.less'
|
||||||
const [users, setUsers] = useState([])
|
|
||||||
|
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 [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(() => {
|
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 (
|
return (
|
||||||
<Modal visible={show} onCancel={() => onClose(false)} onOk={onModalOk}>
|
<Modal
|
||||||
<Transfer />
|
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>
|
</Modal>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -7,64 +7,77 @@ import DownloadLink from '@components/DownloadLink'
|
|||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { makeColumn, makeDateColumn, makeTextColumn, Table } from '@components/Table'
|
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 WellCaseEditor from './WellCaseEditor'
|
||||||
import { HistoryTable } from './HistoryTable'
|
import { HistoryTable } from './HistoryTable'
|
||||||
|
import UploadForm from '@asb/components/UploadForm'
|
||||||
|
|
||||||
const columns = [
|
const expandable = {
|
||||||
makeTextColumn('Категория', 'caption'),
|
expandedRowRender: (category) => (
|
||||||
makeColumn('Файл', 'file', {
|
<HistoryTable category={category} />
|
||||||
render: (file) => file ? (
|
)
|
||||||
<DownloadLink file={file} />
|
}
|
||||||
) : (
|
|
||||||
<span>Файл не загружен</span>
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
makeDateColumn('Дата загрузки', 'uploadDate'),
|
|
||||||
makeColumn('Ответственные', 'responsible', {
|
|
||||||
render: (responsible) => responsible.map((user) => (
|
|
||||||
<UserView user={user} />
|
|
||||||
)),
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
|
|
||||||
const WellCase = memo(() => {
|
const WellCase = memo(() => {
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [categories, setCategories] = useState([])
|
const [categories, setCategories] = useState([])
|
||||||
const [canEdit, setCanEdit] = useState(false)
|
const [canEdit, setCanEdit] = useState(false)
|
||||||
const [showEdit, setShowEdit] = useState(false)
|
const [showEdit, setShowEdit] = useState(false)
|
||||||
const [users, setUsers] = useState([])
|
|
||||||
|
|
||||||
const [well] = useWell()
|
const [well] = useWell()
|
||||||
|
|
||||||
const updateTable = useCallback(() => {
|
const updateTable = useCallback(() => {
|
||||||
invokeWebApiWrapperAsync(
|
invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
await delay(1000)
|
const { permissionToSetPubliher, wellFinalDocuments } = await WellFinalDocumentsService.get(well.id)
|
||||||
const categories = [{ responsible: [{}] }]
|
|
||||||
|
|
||||||
setCanEdit(true)
|
setCategories(wellFinalDocuments.map((cat) => ({ ...cat, uploadDate: cat.file?.uploadDate })))
|
||||||
const showingCategories = categories.filter((cat) => cat.responsible && cat.responsible?.length > 0)
|
setCanEdit(permissionToSetPubliher)
|
||||||
setCategories(showingCategories)
|
|
||||||
},
|
},
|
||||||
setIsLoading,
|
setIsLoading,
|
||||||
'Не удалось загрузить список категорий',
|
'Не удалось загрузить список категорий',
|
||||||
|
{ actionName: 'Загрузка списка категорий', well }
|
||||||
)
|
)
|
||||||
}, [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) => {
|
const onEditClose = useCallback((changed = false) => {
|
||||||
setShowEdit(false)
|
setShowEdit(false)
|
||||||
if (changed) updateTable()
|
if (changed) updateTable()
|
||||||
}, [updateTable])
|
}, [updateTable])
|
||||||
|
|
||||||
const expandable = useMemo(() => ({
|
useEffect(updateTable, [updateTable])
|
||||||
expandedRowRender: (category) => (
|
|
||||||
<HistoryTable users={users} category={category} />
|
|
||||||
)
|
|
||||||
}), [users])
|
|
||||||
|
|
||||||
useEffect(() => updateTable(), [updateTable])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -80,7 +93,7 @@ const WellCase = memo(() => {
|
|||||||
expandable={expandable}
|
expandable={expandable}
|
||||||
/>
|
/>
|
||||||
</LoaderPortal>
|
</LoaderPortal>
|
||||||
<WellCaseEditor users={users} show={showEdit} onClose={onEditClose} />
|
<WellCaseEditor categories={categories} show={showEdit} onClose={onEditClose} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -89,4 +102,5 @@ export default wrapPrivateComponent(WellCase, {
|
|||||||
title: 'Дело скважины',
|
title: 'Дело скважины',
|
||||||
route: 'well_case',
|
route: 'well_case',
|
||||||
requirements: [],
|
requirements: [],
|
||||||
|
// requirements: ['WellFinalDocuments.get'],
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user