FUEL: init; CustomTable update; updated interfaces/types
This commit is contained in:
@ -3,7 +3,7 @@ import { IconPlus } from '@tabler/icons-react';
|
|||||||
import { CreateField } from '../interfaces/create';
|
import { CreateField } from '../interfaces/create';
|
||||||
import { AxiosResponse } from 'axios';
|
import { AxiosResponse } from 'axios';
|
||||||
import FormFields from './FormFields';
|
import FormFields from './FormFields';
|
||||||
import { Badge, Button, createTableColumn, DataGrid, DataGridBody, DataGridCell, DataGridHeader, DataGridHeaderCell, DataGridRow, Dialog, DialogSurface, DialogTitle, DialogTrigger, Input, Select, TableCellLayout, TableColumnDefinition } from '@fluentui/react-components';
|
import { Badge, Button, createTableColumn, DataGrid, DataGridBody, DataGridCell, DataGridHeader, DataGridHeaderCell, DataGridRow, Dialog, DialogSurface, DialogTitle, DialogTrigger, Input, Select, Spinner, TableCellLayout, TableColumnDefinition } from '@fluentui/react-components';
|
||||||
import { IColumn } from '../interfaces/DataGrid/columns';
|
import { IColumn } from '../interfaces/DataGrid/columns';
|
||||||
|
|
||||||
type CustomTableProps<T> = {
|
type CustomTableProps<T> = {
|
||||||
@ -13,6 +13,7 @@ type CustomTableProps<T> = {
|
|||||||
submitHandler?: (data: T) => Promise<AxiosResponse>
|
submitHandler?: (data: T) => Promise<AxiosResponse>
|
||||||
onEditCell?: (rowId: number, columnId: string, value: any) => any
|
onEditCell?: (rowId: number, columnId: string, value: any) => any
|
||||||
searchable?: boolean
|
searchable?: boolean
|
||||||
|
isLoading?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomTable = <T extends object>({
|
const CustomTable = <T extends object>({
|
||||||
@ -20,7 +21,8 @@ const CustomTable = <T extends object>({
|
|||||||
columns,
|
columns,
|
||||||
createFields,
|
createFields,
|
||||||
submitHandler,
|
submitHandler,
|
||||||
searchable = false
|
searchable = false,
|
||||||
|
isLoading = false
|
||||||
}: CustomTableProps<T>) => {
|
}: CustomTableProps<T>) => {
|
||||||
const [data, setData] = useState<(T & { id: number })[]>(initialData);
|
const [data, setData] = useState<(T & { id: number })[]>(initialData);
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
@ -38,7 +40,7 @@ const CustomTable = <T extends object>({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnDefinitions: TableColumnDefinition<any>[] = columns.map(column => (
|
const columnDefinitions: TableColumnDefinition<any>[] = columns.filter(column => column.hidden !== true).map(column => (
|
||||||
createTableColumn<any>({
|
createTableColumn<any>({
|
||||||
columnId: column.name,
|
columnId: column.name,
|
||||||
renderHeaderCell: () => column.header,
|
renderHeaderCell: () => column.header,
|
||||||
@ -170,27 +172,33 @@ const CustomTable = <T extends object>({
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataGrid
|
{isLoading ?
|
||||||
items={data}
|
<Spinner />
|
||||||
columns={columnDefinitions}
|
:
|
||||||
resizableColumns
|
<DataGrid
|
||||||
focusMode="cell"
|
items={data}
|
||||||
>
|
columns={columnDefinitions}
|
||||||
<DataGridHeader>
|
resizableColumns
|
||||||
<DataGridRow>
|
sortable
|
||||||
{({ renderHeaderCell }) => (
|
getRowId={(item) => item.name}
|
||||||
<DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>
|
focusMode="cell"
|
||||||
)}
|
>
|
||||||
</DataGridRow>
|
<DataGridHeader>
|
||||||
</DataGridHeader>
|
<DataGridRow>
|
||||||
<DataGridBody>
|
{({ renderHeaderCell }) => (
|
||||||
{({ item, rowId }) => (
|
<DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>
|
||||||
<DataGridRow key={rowId}>
|
)}
|
||||||
{({ renderCell }) => <DataGridCell>{renderCell(item)}</DataGridCell>}
|
|
||||||
</DataGridRow>
|
</DataGridRow>
|
||||||
)}
|
</DataGridHeader>
|
||||||
</DataGridBody>
|
<DataGridBody<CustomTableProps<T>>>
|
||||||
</DataGrid>
|
{({ item, rowId }) => (
|
||||||
|
<DataGridRow key={rowId}>
|
||||||
|
{({ renderCell }) => <DataGridCell>{renderCell(item)}</DataGridCell>}
|
||||||
|
</DataGridRow>
|
||||||
|
)}
|
||||||
|
</DataGridBody>
|
||||||
|
</DataGrid>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { IconComponents, IconDeviceDesktopAnalytics, IconFlame, IconLogin, IconL
|
|||||||
import SignIn from "../pages/auth/SignIn";
|
import SignIn from "../pages/auth/SignIn";
|
||||||
import SignUp from "../pages/auth/SignUp";
|
import SignUp from "../pages/auth/SignUp";
|
||||||
import PasswordReset from "../pages/auth/PasswordReset";
|
import PasswordReset from "../pages/auth/PasswordReset";
|
||||||
import ComponentTest from "../pages/ComponentTest";
|
|
||||||
import MonitorPage from "../pages/MonitorPage";
|
import MonitorPage from "../pages/MonitorPage";
|
||||||
import Settings from "../pages/Settings";
|
import Settings from "../pages/Settings";
|
||||||
import Users from "../pages/Users";
|
import Users from "../pages/Users";
|
||||||
@ -10,13 +9,16 @@ import Roles from "../pages/Roles";
|
|||||||
import Documents from "../pages/Documents";
|
import Documents from "../pages/Documents";
|
||||||
import Reports from "../pages/Reports";
|
import Reports from "../pages/Reports";
|
||||||
import Servers from "../pages/Servers";
|
import Servers from "../pages/Servers";
|
||||||
import Boilers from "../pages/Boilers";
|
import Boilers from "../pages/fuel/Fuel/Boilers";
|
||||||
import MapTest from "../pages/MapTest";
|
import MapTest from "../pages/MapTest";
|
||||||
import PrintReport from "../pages/PrintReport";
|
import PrintReport from "../pages/PrintReport";
|
||||||
import DBManager from "../pages/DBManager";
|
import DBManager from "../pages/DBManager";
|
||||||
import MapLineTest from "../components/map/MapLineTest";
|
import MapLineTest from "../components/map/MapLineTest";
|
||||||
import FuelPage from "../pages/Fuel";
|
import FuelPage from "../pages/Fuel";
|
||||||
import { Building24Color, Cloud24Color, Database24Color, Document24Color, Form24Color, Map24Filled, Map24Regular, PeopleList24Color, Shield24Color } from "@fluentui/react-icons"
|
import { Building24Color, Cloud24Color, Database24Color, Diversity24Color, Document24Color, Form24Color, Gauge24Color, Map24Filled, Map24Regular, PeopleList24Color, Shield24Color } from "@fluentui/react-icons"
|
||||||
|
import LimitsPage from "../pages/fuel/Limits";
|
||||||
|
import ReportsPage from "../pages/fuel/Reports";
|
||||||
|
import FuelsPage from "../pages/fuel/Fuel/Fuels";
|
||||||
|
|
||||||
// Определение страниц с путями и компонентом для рендера
|
// Определение страниц с путями и компонентом для рендера
|
||||||
|
|
||||||
@ -115,13 +117,40 @@ const pages = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Котельные",
|
label: "Котельные",
|
||||||
path: "/boilers",
|
path: "/fuel/boilers",
|
||||||
icon: <Building24Color />,
|
icon: <Building24Color />,
|
||||||
component: <Boilers />,
|
component: <Boilers />,
|
||||||
drawer: true,
|
drawer: true,
|
||||||
dashboard: true,
|
dashboard: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Виды топлива",
|
||||||
|
path: "/fuel/fuels",
|
||||||
|
icon: <Diversity24Color />,
|
||||||
|
component: <FuelsPage />,
|
||||||
|
drawer: true,
|
||||||
|
dashboard: true,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Лимиты",
|
||||||
|
path: "/fuel/limits",
|
||||||
|
icon: <Gauge24Color />,
|
||||||
|
component: <LimitsPage />,
|
||||||
|
drawer: true,
|
||||||
|
dashboard: true,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Отчеты",
|
||||||
|
path: "/fuel/reports",
|
||||||
|
icon: <Form24Color />,
|
||||||
|
component: <ReportsPage />,
|
||||||
|
drawer: true,
|
||||||
|
dashboard: true,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// label: "ИКС",
|
// label: "ИКС",
|
||||||
// path: "/map-test",
|
// path: "/map-test",
|
||||||
@ -149,15 +178,6 @@ const pages = [
|
|||||||
dashboard: true,
|
dashboard: true,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: "Component test",
|
|
||||||
path: "/component-test",
|
|
||||||
icon: <IconComponents />,
|
|
||||||
component: <ComponentTest />,
|
|
||||||
drawer: true,
|
|
||||||
dashboard: true,
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "Print report test",
|
label: "Print report test",
|
||||||
path: "/print-report-test",
|
path: "/print-report-test",
|
||||||
|
|||||||
@ -14,4 +14,9 @@ export interface IBoiler {
|
|||||||
boiler_code: string;
|
boiler_code: string;
|
||||||
id_city: number;
|
id_city: number;
|
||||||
activity: boolean;
|
activity: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FuelType = {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
}
|
}
|
||||||
@ -24,6 +24,13 @@ export interface IObjectValue {
|
|||||||
date_po: string | null
|
date_po: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type IObjectParamFormat =
|
||||||
|
'bit' |
|
||||||
|
'int' | 'smallint' | 'bigint' | 'tinyint' |
|
||||||
|
'smalldatetime' | 'calculate' |
|
||||||
|
'TCB' | 'GTCB' |
|
||||||
|
'year' | 'uniqueidentifier' | 'group' | 'groupcalculate' | 'array' | string
|
||||||
|
|
||||||
export interface IObjectParam {
|
export interface IObjectParam {
|
||||||
id_object: string
|
id_object: string
|
||||||
id_param: number
|
id_param: number
|
||||||
@ -31,7 +38,7 @@ export interface IObjectParam {
|
|||||||
date_s: string | null
|
date_s: string | null
|
||||||
date_po: string | null
|
date_po: string | null
|
||||||
id_user: number
|
id_user: number
|
||||||
format: string
|
format: IObjectParamFormat
|
||||||
vtable: string
|
vtable: string
|
||||||
exact_format: string | null
|
exact_format: string | null
|
||||||
unit: string | null
|
unit: string | null
|
||||||
|
|||||||
@ -2,14 +2,13 @@ import { IconMathMax, IconPlus, IconTableMinus } from "@tabler/icons-react";
|
|||||||
import { FuelExpenseDtoHeaders, FuelLimitDtoHeaders } from "../dto/fuel/fuel.dto";
|
import { FuelExpenseDtoHeaders, FuelLimitDtoHeaders } from "../dto/fuel/fuel.dto";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { fetcher } from "../http/axiosInstanceNest";
|
import { fetcher } from "../http/axiosInstanceNest";
|
||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
import { SubmitHandler, useForm } from "react-hook-form";
|
import { SubmitHandler, useForm } from "react-hook-form";
|
||||||
|
|
||||||
import { AgGridReact } from "ag-grid-react";
|
import { AgGridReact } from "ag-grid-react";
|
||||||
import { AllCommunityModule, ColDef, ModuleRegistry } from 'ag-grid-community'
|
import { AllCommunityModule, ColDef, ModuleRegistry } from 'ag-grid-community'
|
||||||
import { CalendarStrings, DatePicker, defaultDatePickerStrings } from "@fluentui/react-datepicker-compat"
|
import { CalendarStrings, DatePicker, defaultDatePickerStrings } from "@fluentui/react-datepicker-compat"
|
||||||
import { Button, Dialog, DialogSurface, DialogTitle, DialogTrigger, Field, Input, Spinner, Tab, TabList } from "@fluentui/react-components";
|
import { Button, Dialog, DialogSurface, DialogTitle, DialogTrigger, Field, Input, Spinner, Tab, TabList } from "@fluentui/react-components";
|
||||||
import { useAppStore } from "../store/app";
|
|
||||||
|
|
||||||
ModuleRegistry.registerModules([AllCommunityModule])
|
ModuleRegistry.registerModules([AllCommunityModule])
|
||||||
|
|
||||||
@ -94,16 +93,6 @@ export default function FuelPage() {
|
|||||||
|
|
||||||
const { data, isLoading } = useSWR(currentTab.get, () => fetcher(currentTab.get), { revalidateOnFocus: false })
|
const { data, isLoading } = useSWR(currentTab.get, () => fetcher(currentTab.get), { revalidateOnFocus: false })
|
||||||
|
|
||||||
const { colorScheme } = useAppStore()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (colorScheme === 'dark') {
|
|
||||||
document.body.dataset.agThemeMode = 'dark'
|
|
||||||
} else {
|
|
||||||
document.body.dataset.agThemeMode = 'light'
|
|
||||||
}
|
|
||||||
}, [colorScheme])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
|
||||||
@ -137,7 +126,6 @@ export default function FuelPage() {
|
|||||||
<div style={{
|
<div style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
overflow: 'auto'
|
|
||||||
}}>
|
}}>
|
||||||
{tables.map((table, index) => {
|
{tables.map((table, index) => {
|
||||||
if (table.value === currentTab.value) {
|
if (table.value === currentTab.value) {
|
||||||
@ -147,12 +135,11 @@ export default function FuelPage() {
|
|||||||
<Spinner />
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div style={{ overflow: 'auto', width: '100%', height: '100%', padding: '1rem' }}>
|
<div style={{ width: 'auto', height: '100%', padding: '1rem' }}>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
key={index}
|
key={index}
|
||||||
//rowData={data}
|
|
||||||
// rowData={[
|
// rowData={[
|
||||||
// Object.keys(table.headers).reduce((obj, key) => ({ ...obj, [key]: 'test' }), {}),
|
// Object.keys(table.headers).reduce((obj, key) => ({ ...obj, [key]: 'test1' }), {}),
|
||||||
// Object.keys(table.headers).reduce((obj, key) => ({ ...obj, [key]: 'test' }), {})
|
// Object.keys(table.headers).reduce((obj, key) => ({ ...obj, [key]: 'test' }), {})
|
||||||
// ]}
|
// ]}
|
||||||
rowData={data}
|
rowData={data}
|
||||||
|
|||||||
198
client/src/pages/fuel/Fuel/Boilers.tsx
Normal file
198
client/src/pages/fuel/Fuel/Boilers.tsx
Normal 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
|
||||||
47
client/src/pages/fuel/Fuel/Flow.tsx
Normal file
47
client/src/pages/fuel/Fuel/Flow.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { Text } from '@fluentui/react-components'
|
||||||
|
|
||||||
|
const FlowPage = () => {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: '1rem',
|
||||||
|
width: '100%',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
{/* <Portal mountNode={document.querySelector('#header-portal')}>
|
||||||
|
|
||||||
|
</Portal> */}
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<Text size={600} weight='bold'>
|
||||||
|
Приход и расход топлива
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text size={400} weight='medium'>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowPage
|
||||||
53
client/src/pages/fuel/Fuel/FuelRenderer.tsx
Normal file
53
client/src/pages/fuel/Fuel/FuelRenderer.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { Button, Spinner, Table, TableBody, TableCell, TableCellActions, TableCellLayout, TableRow } from '@fluentui/react-components';
|
||||||
|
import { Add12Regular, DeleteRegular, EditRegular } from '@fluentui/react-icons';
|
||||||
|
import type { CustomCellRendererProps } from 'ag-grid-react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
|
||||||
|
export default (params: CustomCellRendererProps) => {
|
||||||
|
const { data: fuelTypes } = useSWR('/fuel/fuel-types', () => axios.get(`/fuel/fuel-types`, {
|
||||||
|
baseURL: import.meta.env.VITE_API_NEST_URL
|
||||||
|
}).then(res => res.data))
|
||||||
|
|
||||||
|
if (fuelTypes) {
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', padding: '0.25rem', gap: '0.5rem' }}>
|
||||||
|
{Array.isArray(params.value) && params.value.length > 0 &&
|
||||||
|
<Table style={{ width: '100%' }} size='small'>
|
||||||
|
<TableBody>
|
||||||
|
{Array.isArray(params.value) && params.value.map(fuel => (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>
|
||||||
|
<TableCellLayout truncate>
|
||||||
|
{fuel.name}
|
||||||
|
</TableCellLayout>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<TableCellLayout truncate>
|
||||||
|
{fuelTypes && Array.isArray(fuelTypes) &&
|
||||||
|
fuelTypes.find(ft => ft.id === fuel.id_fuels).name
|
||||||
|
}
|
||||||
|
</TableCellLayout>
|
||||||
|
|
||||||
|
<TableCellActions>
|
||||||
|
<Button icon={<EditRegular />} appearance='subtle' />
|
||||||
|
<Button icon={<DeleteRegular color='red' />} appearance='subtle' />
|
||||||
|
</TableCellActions>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
}
|
||||||
|
|
||||||
|
<Button style={{ width: 'min-content' }} appearance='primary' icon={<Add12Regular />} size='small'>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Spinner />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
43
client/src/pages/fuel/Fuel/FuelTypeEditor.tsx
Normal file
43
client/src/pages/fuel/Fuel/FuelTypeEditor.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { Combobox, Option, Spinner } from "@fluentui/react-components";
|
||||||
|
import { CustomCellEditorProps } from "ag-grid-react";
|
||||||
|
import axios from "axios";
|
||||||
|
import useSWR from "swr";
|
||||||
|
|
||||||
|
export default ({ value, onValueChange }: CustomCellEditorProps) => {
|
||||||
|
const { data: fuelTypes } = useSWR('/fuel/fuel-types', () => axios.get(`/fuel/fuel-types`, {
|
||||||
|
baseURL: import.meta.env.VITE_API_NEST_URL
|
||||||
|
}).then(res => res.data))
|
||||||
|
|
||||||
|
if (fuelTypes) {
|
||||||
|
return (
|
||||||
|
<Combobox
|
||||||
|
autoFocus
|
||||||
|
placeholder="Тип топлива"
|
||||||
|
clearable
|
||||||
|
value={fuelTypes.find((f: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}) => f.id === value).name}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
marginTop: '-4px'
|
||||||
|
}}
|
||||||
|
size='small'
|
||||||
|
onOptionSelect={(_, data) => {
|
||||||
|
onValueChange(data.optionValue === '' || data.optionValue === undefined ? null : data.optionValue)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{fuelTypes && Array.isArray(fuelTypes) && fuelTypes.map((option) => (
|
||||||
|
<Option key={option.id} text={option.name} value={option.id}>
|
||||||
|
{option.name}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Combobox>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Spinner />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
25
client/src/pages/fuel/Fuel/FuelTypeRenderer.tsx
Normal file
25
client/src/pages/fuel/Fuel/FuelTypeRenderer.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Spinner } from '@fluentui/react-components';
|
||||||
|
import type { CustomCellRendererProps } from 'ag-grid-react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
|
||||||
|
export default (params: CustomCellRendererProps) => {
|
||||||
|
const { data: fuelTypes } = useSWR('/fuel/fuel-types', () => axios.get(`/fuel/fuel-types`, {
|
||||||
|
baseURL: import.meta.env.VITE_API_NEST_URL
|
||||||
|
}).then(res => res.data))
|
||||||
|
|
||||||
|
if (fuelTypes) {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{fuelTypes.find((t: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}) => t.id === params.value).name}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Spinner />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
34
client/src/pages/fuel/Fuel/FuelTypes.tsx
Normal file
34
client/src/pages/fuel/Fuel/FuelTypes.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Text } from '@fluentui/react-components'
|
||||||
|
|
||||||
|
const FuelTypesPage = () => {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: '1rem',
|
||||||
|
width: '100%',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
{/* <Portal mountNode={document.querySelector('#header-portal')}>
|
||||||
|
|
||||||
|
</Portal> */}
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<Text size={600} weight='bold'>
|
||||||
|
Виды топлива
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text size={400} weight='medium'>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FuelTypesPage
|
||||||
185
client/src/pages/fuel/Fuel/Fuels.tsx
Normal file
185
client/src/pages/fuel/Fuel/Fuels.tsx
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
import { Button, Combobox, Dialog, DialogActions, DialogBody, DialogContent, DialogSurface, DialogTitle, DialogTrigger, Field, Input, Option, Tab, TabList, Text } from '@fluentui/react-components'
|
||||||
|
import useSWR from 'swr'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { AgGridReact } from 'ag-grid-react'
|
||||||
|
import { Controller, SubmitHandler, useForm } from 'react-hook-form'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { FuelType } from '../../../interfaces/fuel'
|
||||||
|
|
||||||
|
type Inputs = {
|
||||||
|
id_fuel_type: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const FuelsPage = () => {
|
||||||
|
const [selectedIdFuels, setSelectedIdFuels] = useState<number | null>(null)
|
||||||
|
|
||||||
|
const { data: fuelTypes } = useSWR('/fuel/fuel-types', () => axios.get(`/fuel/fuel-types`, {
|
||||||
|
baseURL: import.meta.env.VITE_API_NEST_URL
|
||||||
|
}).then(res => {
|
||||||
|
setSelectedIdFuels(res.data[0].id)
|
||||||
|
return res.data
|
||||||
|
}))
|
||||||
|
|
||||||
|
const { data: fuels, mutate: mutateFuels, isLoading: fuelsLoading } = useSWR(selectedIdFuels ? `/fuel/fuels?id_fuels=${selectedIdFuels}` : null, () => axios.get(`/fuel/fuels?id_fuels=${selectedIdFuels}`, {
|
||||||
|
baseURL: import.meta.env.VITE_API_NEST_URL
|
||||||
|
}).then(res => res.data))
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
control,
|
||||||
|
//formState: { errors, isSubmitting },
|
||||||
|
} = useForm<Inputs>()
|
||||||
|
|
||||||
|
const onSubmit: SubmitHandler<Inputs> = (data) => {
|
||||||
|
console.log(data)
|
||||||
|
mutateFuels([...fuels, data])
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log("done")
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: '1rem',
|
||||||
|
width: '100%',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<Text size={600} weight='bold'>
|
||||||
|
Виды топлива
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger>
|
||||||
|
<Button appearance='primary' style={{ width: 'min-content' }}>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
|
||||||
|
<DialogSurface>
|
||||||
|
{fuelTypes &&
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)} >
|
||||||
|
<DialogBody>
|
||||||
|
<DialogTitle>Добавление вида топлива</DialogTitle>
|
||||||
|
|
||||||
|
<DialogContent style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
|
||||||
|
<Controller
|
||||||
|
name='id_fuel_type'
|
||||||
|
control={control}
|
||||||
|
rules={{
|
||||||
|
required: true
|
||||||
|
}}
|
||||||
|
render={({ field: { value, onChange } }) => {
|
||||||
|
return (
|
||||||
|
<Field label={'Тип топлива'}>
|
||||||
|
<Combobox
|
||||||
|
autoFocus
|
||||||
|
placeholder="Тип топлива"
|
||||||
|
clearable
|
||||||
|
value={fuelTypes.find((f: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}) => f.id.toString() == value)?.name || ''}
|
||||||
|
size='medium'
|
||||||
|
onOptionSelect={(_, data) => {
|
||||||
|
onChange(data.optionValue)
|
||||||
|
//onValueChange(data.optionValue === '' || data.optionValue === undefined ? null : data.optionValue)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{fuelTypes && Array.isArray(fuelTypes) && fuelTypes.map((option) => (
|
||||||
|
<Option key={option.id} text={option.name} value={option.id}>
|
||||||
|
{option.name}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Combobox>
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Field label={'Наименование'}>
|
||||||
|
<Input {...register('name', { required: true })} />
|
||||||
|
</Field>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<Button type='submit' appearance='primary'>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</DialogBody>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
|
</DialogSurface>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{fuelTypes && Array.isArray(fuelTypes) &&
|
||||||
|
<TabList selectedValue={selectedIdFuels} onTabSelect={(_, data) => {
|
||||||
|
setSelectedIdFuels(Number(data.value))
|
||||||
|
}}>
|
||||||
|
{fuelTypes && Array.isArray(fuelTypes) && fuelTypes.map((ft: FuelType) => (
|
||||||
|
<Tab id={ft.id.toString()} value={ft.id}>
|
||||||
|
{ft.name}
|
||||||
|
</Tab>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</TabList>}
|
||||||
|
|
||||||
|
<AgGridReact
|
||||||
|
key={`fuels`}
|
||||||
|
loading={fuelsLoading}
|
||||||
|
overlayLoadingTemplate='Загрузка...'
|
||||||
|
overlayNoRowsTemplate='Нет данных'
|
||||||
|
rowData={fuels}
|
||||||
|
columnDefs={[
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
headerName: 'Наименование'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tnt',
|
||||||
|
headerName: 'Перевод в натуральный показатель'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tut',
|
||||||
|
headerName: 'Перевод в условный показатель'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'koef',
|
||||||
|
headerName: 'Коэффициент'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'Gk',
|
||||||
|
headerName: 'Гк'
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// field: 'id_fuels',
|
||||||
|
// headerName: 'Вид топлива',
|
||||||
|
// editable: true,
|
||||||
|
// cellEditor: FuelTypeEditor,
|
||||||
|
// cellRenderer: FuelTypeRenderer,
|
||||||
|
// enableCellChangeFlash: true
|
||||||
|
// },
|
||||||
|
]}
|
||||||
|
defaultColDef={{
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FuelsPage
|
||||||
7
client/src/pages/fuel/Limits.tsx
Normal file
7
client/src/pages/fuel/Limits.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const LimitsPage = () => {
|
||||||
|
return (
|
||||||
|
<div>LimitsPage</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LimitsPage
|
||||||
69
client/src/pages/fuel/Reports.tsx
Normal file
69
client/src/pages/fuel/Reports.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { Button, CompoundButton, Text } from '@fluentui/react-components'
|
||||||
|
|
||||||
|
const ReportsPage = () => {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: '1rem',
|
||||||
|
width: '100%',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
{/* <Portal mountNode={document.querySelector('#header-portal')}>
|
||||||
|
|
||||||
|
</Portal> */}
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<Text size={600} weight='bold'>
|
||||||
|
Отчеты
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text size={400} weight='medium'>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<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}>
|
||||||
|
Параметры отчета
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text weight='bold' size={500}>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text weight='regular' size={200} style={{ color: 'gray' }}>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button>
|
||||||
|
|
||||||
|
</Button>
|
||||||
|
</CompoundButton>
|
||||||
|
|
||||||
|
{/* {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>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReportsPage
|
||||||
9
client/src/pages/fuel/Transport/Drivers.tsx
Normal file
9
client/src/pages/fuel/Transport/Drivers.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const DriversPage = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DriversPage
|
||||||
7
client/src/pages/fuel/Transport/Routes.tsx
Normal file
7
client/src/pages/fuel/Transport/Routes.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const RoutesPage = () => {
|
||||||
|
return (
|
||||||
|
<div>RoutesPage</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RoutesPage
|
||||||
7
client/src/pages/fuel/Transport/Transport.tsx
Normal file
7
client/src/pages/fuel/Transport/Transport.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const TransportPage = () => {
|
||||||
|
return (
|
||||||
|
<div>TransportPage</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TransportPage
|
||||||
69
client/src/pages/fuel/Transport/Waybills.tsx
Normal file
69
client/src/pages/fuel/Transport/Waybills.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { Button, CompoundButton, Text } from '@fluentui/react-components'
|
||||||
|
|
||||||
|
const WaybillsPage = () => {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: '1rem',
|
||||||
|
width: '100%',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
{/* <Portal mountNode={document.querySelector('#header-portal')}>
|
||||||
|
|
||||||
|
</Portal> */}
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<Text size={600} weight='bold'>
|
||||||
|
Путевые листы
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text size={400} weight='medium'>
|
||||||
|
Управление маршрутами и учет расхода топлива
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<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}>
|
||||||
|
Параметры отчета
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text weight='bold' size={500}>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text weight='regular' size={200} style={{ color: 'gray' }}>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button>
|
||||||
|
|
||||||
|
</Button>
|
||||||
|
</CompoundButton>
|
||||||
|
|
||||||
|
{/* {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>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WaybillsPage
|
||||||
Reference in New Issue
Block a user