FUEL: init; CustomTable update; updated interfaces/types

This commit is contained in:
2025-11-14 17:16:22 +09:00
parent 38b041cfa5
commit d04b03ac29
18 changed files with 833 additions and 53 deletions

View File

@ -0,0 +1,198 @@
import { useEffect, useState } from 'react'
import { Combobox, CompoundButton, Option, Text } from '@fluentui/react-components'
import useSWR from 'swr'
import axios from 'axios'
import { AgGridReact, CustomCellRendererProps } from 'ag-grid-react'
import { AllCommunityModule, ModuleRegistry } from 'ag-grid-community'
import FuelRenderer from './FuelRenderer'
ModuleRegistry.registerModules([AllCommunityModule])
function Boilers() {
const [, setBoilersPage] = useState(1)
const [boilerSearch, setBoilerSearch] = useState("")
const [, setDebouncedBoilerSearch] = useState("")
// const { boilers } = useBoilers(10, boilersPage, debouncedBoilerSearch)
const { data: regions } = useSWR('/general/regions', () => axios.get('/general/regions', {
baseURL: import.meta.env.VITE_API_NEST_URL
}).then(res => res.data))
const [regionId, setRegionId] = useState<number | undefined>(undefined)
const { data: cities } = useSWR(regionId ? `/general/cities?region_id=${regionId}` : null, () => axios.get(`/general/cities?region_id=${regionId}`, {
baseURL: import.meta.env.VITE_API_NEST_URL
}).then(res => res.data))
const [cityId, setCityId] = useState<number | undefined>(undefined)
const { data: boilers, isLoading: boilersLoading } = useSWR(cityId !== undefined ? `/fuel/boilers?city_id=${cityId}&offset=0&limit=100` : null, () => axios.get(`/fuel/boilers?city_id=${cityId}&offset=0&limit=100`, {
baseURL: import.meta.env.VITE_API_NEST_URL
}).then(res => res.data))
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedBoilerSearch(boilerSearch)
}, 500)
return () => {
clearTimeout(handler)
}
}, [boilerSearch])
useEffect(() => {
setBoilersPage(1)
setBoilerSearch("")
}, [])
return (
<div style={{
display: 'flex',
flexDirection: 'column',
padding: '1rem',
width: '100%',
gap: '1rem'
}}>
{/* <Portal mountNode={document.querySelector('#header-portal')}>
</Portal> */}
<div style={{ display: 'flex', gap: '1rem' }}>
<Combobox
placeholder="Выберите регион"
clearable
onOptionSelect={(_, data) => {
if (data.optionValue) {
setRegionId(Number(data.optionValue))
} else {
setCityId(undefined)
setRegionId(undefined)
}
}}
>
{regions && Array.isArray(regions) && regions.map((option) => (
<Option key={option.id} text={option.name} value={option.id}>
{option.name}
</Option>
))}
</Combobox>
{cities && <Combobox
clearable
placeholder="Выберите населенный пункт"
onOptionSelect={(_, data) => {
if (data.optionValue) {
setCityId(Number(data.optionValue))
} else {
setCityId(undefined)
}
}}
>
{cities && Array.isArray(cities) && cities.map((option) => (
<Option key={option.id} text={option.name} value={option.id}>
{option.name}
</Option>
))}
</Combobox>}
</div>
<div style={{
display: 'flex',
width: '100%',
flexDirection: 'column',
gap: '1rem'
}}>
<Text size={400} weight='medium'>
{cityId && cities && Array.isArray(cities) && cities.find(city => city.id === cityId).name}
</Text>
{cityId &&
<div style={{ display: 'flex', width: '100%', gap: '1rem', justifyContent: 'space-between' }}>
<BoilersCard title='Всего объектов' value={boilers && Array.isArray(boilers) ? boilers.length.toString() : ''} subtitle='' />
<BoilersCard title='Общий остаток' value={''} subtitle='' />
<BoilersCard title='Лимит на сезон' value={''} subtitle='' />
<BoilersCard title='Требуют внимания' value={''} subtitle='' />
</div>
}
</div>
<AgGridReact
// rowData={[
// Object.keys(table.headers).reduce((obj, key) => ({ ...obj, [key]: 'test1' }), {}),
// Object.keys(table.headers).reduce((obj, key) => ({ ...obj, [key]: 'test' }), {})
// ]}
key={`boilers-${cityId}`}
loading={boilersLoading}
overlayLoadingTemplate='Загрузка...'
overlayNoRowsTemplate='Нет данных'
rowData={boilers}
columnDefs={[
{
field: 'boiler_name',
headerName: 'Наименование'
},
{
field: 'boiler_code',
headerName: 'Идент. код'
},
{
field: 'id_fuels',
headerName: 'Вид топлива',
//editable: true,
//cellEditor: FuelTypeEditor,
autoHeight: true,
cellRenderer: FuelRenderer,
cellStyle: (_) => {
return { padding: '1px' }
}
//enableCellChangeFlash: true
},
{
field: 'activity',
headerName: 'Активный',
cellRenderer: (params: CustomCellRendererProps) => (<span>{params.value === true ? 'Да' : 'Нет'}</span>)
}
]}
defaultColDef={{
flex: 1,
}}
/>
</div>
)
}
const BoilersCard = ({
title,
value,
subtitle,
}: {
title: string
value: string
subtitle: string
}) => {
return (
<CompoundButton
onClick={() => { }}
style={{ display: 'flex', width: '100%', justifyContent: 'flex-start', flexDirection: 'column', gap: '2rem', alignItems: 'flex-start', cursor: 'pointer', userSelect: 'none' }}
//icon={icon}
>
<Text weight='bold' size={300}>
{title}
</Text>
<Text weight='bold' size={500}>
{value}
</Text>
<Text weight='regular' size={200} style={{ color: 'gray' }}>
{subtitle}
</Text>
</CompoundButton>
)
}
export default Boilers