149 lines
4.5 KiB
TypeScript
149 lines
4.5 KiB
TypeScript
|
|
import { useCallback, useEffect, useState } from 'react'
|
|||
|
|
import { GridDto } from '@/proxy/form/models'
|
|||
|
|
import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource'
|
|||
|
|
import { Pagination, Select } from '@/components/ui'
|
|||
|
|
import classNames from 'classnames'
|
|||
|
|
import { getList } from '@/services/form.service'
|
|||
|
|
import { FaInbox } from 'react-icons/fa'
|
|||
|
|
import FormView from '../form/FormView'
|
|||
|
|
|
|||
|
|
interface CardProps {
|
|||
|
|
listFormCode: string
|
|||
|
|
searchParams?: URLSearchParams
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type Option = {
|
|||
|
|
value: number
|
|||
|
|
label: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const CardItem = ({
|
|||
|
|
row,
|
|||
|
|
gridDto,
|
|||
|
|
listFormCode,
|
|||
|
|
}: {
|
|||
|
|
row: any
|
|||
|
|
gridDto: GridDto
|
|||
|
|
listFormCode: string
|
|||
|
|
}) => {
|
|||
|
|
const keyField = gridDto.gridOptions.keyFieldName
|
|||
|
|
const rowId = row[keyField!]
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="bg-white dark:bg-neutral-800 border dark:border-neutral-700 flex flex-col p-4">
|
|||
|
|
<div className="flex-grow">
|
|||
|
|
<FormView listFormCode={listFormCode} id={rowId} isSubForm={true} />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const Card = ({ listFormCode, searchParams }: CardProps) => {
|
|||
|
|
const { createSelectDataSource } = useListFormCustomDataSource({})
|
|||
|
|
const [gridDto, setGridDto] = useState<GridDto>()
|
|||
|
|
const [data, setData] = useState<any[]>([])
|
|||
|
|
const [totalCount, setTotalCount] = useState(0)
|
|||
|
|
const [currentPage, setCurrentPage] = useState(1)
|
|||
|
|
const [pageSize, setPageSize] = useState(20)
|
|||
|
|
const [pageSizeOptions, setPageSizeOptions] = useState<Option[]>([])
|
|||
|
|
|
|||
|
|
const onPageSizeSelect = ({ value }: Option) => {
|
|||
|
|
setPageSize(value)
|
|||
|
|
setCurrentPage(1)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const onPageChange = (page: number) => {
|
|||
|
|
setCurrentPage(page)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const loadData = useCallback(() => {
|
|||
|
|
if (!gridDto) return
|
|||
|
|
|
|||
|
|
const store = createSelectDataSource(gridDto.gridOptions, listFormCode, searchParams)
|
|||
|
|
|
|||
|
|
const loadOptions = {
|
|||
|
|
skip: (currentPage - 1) * pageSize,
|
|||
|
|
take: pageSize,
|
|||
|
|
requireTotalCount: true,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
store.load(loadOptions).then((res: any) => {
|
|||
|
|
setData(res.data)
|
|||
|
|
setTotalCount(res.totalCount || 0)
|
|||
|
|
})
|
|||
|
|
}, [gridDto, listFormCode, searchParams, currentPage, pageSize])
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
getList({ listFormCode }).then((res: any) => setGridDto(res.data))
|
|||
|
|
}, [listFormCode])
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (!gridDto) return
|
|||
|
|
|
|||
|
|
const pagerOptions = gridDto.gridOptions.pagerOptionDto
|
|||
|
|
const allowedSizes =
|
|||
|
|
pagerOptions?.allowedPageSizes
|
|||
|
|
?.split(',')
|
|||
|
|
.map((s) => Number(s.trim()))
|
|||
|
|
.filter((n) => !isNaN(n) && n > 0) || [20, 50, 100]
|
|||
|
|
|
|||
|
|
setPageSizeOptions(allowedSizes.map((size) => ({ value: size, label: `${size} page` })))
|
|||
|
|
}, [gridDto, listFormCode, searchParams])
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
loadData()
|
|||
|
|
}, [loadData])
|
|||
|
|
|
|||
|
|
if (!gridDto) return null
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<>
|
|||
|
|
{data.length === 0 && (
|
|||
|
|
<div className="flex flex-col items-center justify-center p-10 bg-gray-50 dark:bg-neutral-800/50 rounded-md border-2 border-dashed border-gray-200 dark:border-neutral-700">
|
|||
|
|
<div className="text-center">
|
|||
|
|
<FaInbox className="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
|||
|
|
<p className="mt-4 text-lg font-semibold text-gray-700 dark:text-gray-300">
|
|||
|
|
Kayıt Bulunamadı
|
|||
|
|
</p>
|
|||
|
|
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
|
|||
|
|
Görüntülenecek herhangi bir veri yok.
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-4 gap-4">
|
|||
|
|
{data.map((row, idx) => {
|
|||
|
|
const keyField = gridDto.gridOptions.keyFieldName
|
|||
|
|
const rowId = row[keyField!]
|
|||
|
|
|
|||
|
|
return <CardItem key={rowId || idx} row={row} gridDto={gridDto} listFormCode={listFormCode} />
|
|||
|
|
})}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{gridDto.gridOptions.pagerOptionDto?.visible && totalCount > pageSize && (
|
|||
|
|
<div className={classNames('flex items-center justify-between border-t-1 gap-4 mt-4')}>
|
|||
|
|
<div className="flex items-center gap-2">
|
|||
|
|
<span className="text-xs text-gray-600 dark:text-gray-300">
|
|||
|
|
Toplam {totalCount} kayıt
|
|||
|
|
</span>
|
|||
|
|
<Select
|
|||
|
|
size="xs"
|
|||
|
|
menuPlacement="top"
|
|||
|
|
value={pageSizeOptions.find((o) => o.value === pageSize)}
|
|||
|
|
options={pageSizeOptions}
|
|||
|
|
onChange={(selected) => onPageSizeSelect(selected as Option)}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
<Pagination
|
|||
|
|
currentPage={currentPage}
|
|||
|
|
total={totalCount}
|
|||
|
|
pageSize={pageSize}
|
|||
|
|
onChange={onPageChange}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default Card
|