Compare commits

...

2 Commits

Author SHA1 Message Date
gman b19f4ba5d9 translation 2
1 month ago
gman 9765f215db translation
1 month ago

@ -1 +1 @@
VITE_API_URL=https://geoheat.spatialsystems.ru VITE_API_URL=https://geoenergy.spatialsystems.ru

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/index.html vendored

@ -5,7 +5,7 @@
<link href="/vite.svg" rel="icon"/> <link href="/vite.svg" rel="icon"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DZKH by Spatial</title> <title>DZKH by Spatial</title>
<script type="module" crossorigin src="/assets/index.e851803c.js"></script> <script type="module" crossorigin src="/assets/index.d44a9096.js"></script>
<link rel="stylesheet" href="/assets/index.767ffdb3.css"> <link rel="stylesheet" href="/assets/index.767ffdb3.css">
</head> </head>
<body> <body>

@ -1,33 +1,33 @@
import {commonPopupConfig,} from "./config"; import { Button, Col, Row } from "antd";
import {Button, Col, Row} from "antd"; import { useGetRegions } from "../../../components/RegionSelect.jsx";
import {isNil} from "../../../utils.js"; import { tempMapper } from "../../../config.js";
import {useGetRegions} from "../../../components/RegionSelect.jsx"; import { useWeatherFilter } from "../../../dzkh-features/WeatherSlider/useWeatherFilter.js";
import {useSimulateAccident} from "../../../stores/useSimulateAccident.js"; import { useSimulateAccident } from "../../../stores/useSimulateAccident.js";
import {useWeatherFilter} from "../../../dzkh-features/WeatherSlider/useWeatherFilter.js"; import { isNil } from "../../../utils.js";
import {tempMapper} from "../../../config.js"; import { commonPopupConfig, } from "./config";
const dynamicFields = [ const dynamicFields = [
{ {
field: 'prob1', field: 'prob1',
name: 'Отсутствие отопления в доме' name: 'No heating in the building'
},{ },{
field: 'prob2', field: 'prob2',
name: 'Протечка труб в подъезде' name: 'Leaking pipes in the entrance'
},{ },{
field: 'prob3', field: 'prob3',
name: 'Температура в квартире ниже нормативной' name: 'Apartment temperature below standard'
},{ },{
field: 'prob4', field: 'prob4',
name: 'Температура в помещении общего пользования ниже нормативной' name: 'Common area temperature below standard'
},{ },{
field: 'prob5', field: 'prob5',
name: 'Течь в системе отопления' name: 'Leak in the heating system'
},{ },{
field: 'cooling_time', field: 'cooling_time',
name: 'Время остывания (часы)' name: 'Cooling time (hours)'
},{ },{
field: 'priority', field: 'priority',
name: 'Приоритет здания' name: 'Building priority'
} }
] ]
@ -44,7 +44,7 @@ export const FeatureProperties = ({ feature }) => {
if (isSourcePoint) { if (isSourcePoint) {
return [ return [
...commonPopupConfig, {field: `prob6_${tempMapper[temperature]}`, name: 'Авария на ТП'} ...commonPopupConfig, {field: `prob6_${tempMapper[temperature]}`, name: 'Energy source failure'}
] ]
} }
@ -91,7 +91,7 @@ export const FeatureProperties = ({ feature }) => {
})} })}
{isSourcePoint ? {isSourcePoint ?
<div className={'mt-3 text-center'}> <div className={'mt-3 text-center'}>
<Button type={'primary'} onClick={simulateAccident}>Смоделировать аварию</Button> <Button type={'primary'} onClick={simulateAccident}>Simulate failure</Button>
</div> </div>
: null} : null}
</div> </div>

@ -3,19 +3,19 @@ export const getRegionNameById = (id, normalizedRegions) =>
export const commonPopupConfig = [ export const commonPopupConfig = [
{ {
name: "Адрес", name: "Address",
field: "building_address", field: "building_address",
}, },
{ {
name: "Номер ТП", name: "TP number",
field: "tp_number", field: "tp_number",
}, },
{ {
name: "Номер ОДС", name: "Dispatcher center number",
field: "ods_number", field: "ods_number",
}, },
{ {
name: "Телефон ОДС", name: "Dispatcher phone",
field: "phone_number", field: "phone_number",
} }
]; ];

@ -15,9 +15,9 @@ const SingleFeaturePopup = ({ feature }) => {
}; };
const typeMapper = { const typeMapper = {
potreb: 'Потребитель', potreb: 'Consumer',
tp: 'Источник', tp: 'Source',
ods: 'Диспетчерская' ods: 'Dispatch center'
} }
const MultipleFeaturesPopup = ({ features }) => { const MultipleFeaturesPopup = ({ features }) => {

@ -3,7 +3,7 @@ import { Button } from "antd";
export const ClearFiltersButton = ({ onClick, disabled }) => { export const ClearFiltersButton = ({ onClick, disabled }) => {
return ( return (
<Button block className={"mt-2"} onClick={onClick} disabled={disabled}> <Button block className={"mt-2"} onClick={onClick} disabled={disabled}>
Сбросить фильтры Reset filters
</Button> </Button>
); );
}; };

@ -77,13 +77,13 @@ export const RegionSelect = ({
return ( return (
<div> <div>
<Title text={"АО / район"} /> <Title text={"District / area"} />
<TreeSelect <TreeSelect
showSearch showSearch
style={{ width: "100%" }} style={{ width: "100%" }}
value={selectedRegionId} value={selectedRegionId}
dropdownStyle={{ maxHeight: 400, overflow: "auto" }} dropdownStyle={{ maxHeight: 400, overflow: "auto" }}
placeholder="Выберите АО или район" placeholder="Select district or area"
allowClear allowClear
treeDefaultExpandAll={false} treeDefaultExpandAll={false}
onChange={handleChange} onChange={handleChange}
@ -93,7 +93,7 @@ export const RegionSelect = ({
notFoundContent={ notFoundContent={
<Empty <Empty
image={Empty.PRESENTED_IMAGE_SIMPLE} image={Empty.PRESENTED_IMAGE_SIMPLE}
description={"Не найдено"} description={"Not found"}
/> />
} }
disabled={disabled} disabled={disabled}

@ -1,43 +1,43 @@
export const CONSUMER_OPTIONS = [ export const CONSUMER_OPTIONS = [
{ {
value: "category1", value: "category1",
title: "Прогнозирование", title: " Emergency forecasting",
selectable: false, selectable: false,
children: [ children: [
{ {
value: "prob1", value: "prob1",
title: "Отсутствие отопления в доме", title: "No heating in the building",
}, },
{ {
value: "prob2", value: "prob2",
title: "Протечка труб в подъезде", title: "Leaking pipes in the entrance",
}, },
{ {
value: "prob3", value: "prob3",
title: "Температура в квартире ниже нормативной", title: "Apartment temperature below standard",
}, },
{ {
value: "prob4", value: "prob4",
title: "Температура в помещении общего пользования ниже нормативной", title: "Common area temperature below standard",
}, },
{ {
value: "prob5", value: "prob5",
title: "Течь в системе отопления", title: "Leak in the heating system",
}, },
] ]
}, },
{ {
value: "category2", value: "category2",
title: "Реагирование", title: "Emergency response",
selectable: false, selectable: false,
children: [ children: [
{ {
value: "cooling_time", value: "cooling_time",
title: "Время остывания, ч", title: "Cooling time, h",
}, },
{ {
value: "priority", value: "priority",
title: "Приоритет здания", title: "Building priority",
}, },
] ]
} }

@ -11,28 +11,27 @@ export const AccidentSimulationModal = ({id, modalOpen, setModalOpen}) => {
return ( return (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<Row className={twMerge("font-bold")}> <Row className={twMerge("font-bold")}>
В зоне аварии оказалось: In the failure area there are:
</Row> </Row>
{!isNil(data?.potreb_count) && !isNil(data?.potreb_soc_count) && ( {!isNil(data?.potreb_count) && !isNil(data?.potreb_soc_count) && (
<Row> <Row>
{data?.potreb_count + data?.potreb_soc_count} потребителей (из них {data?.potreb_soc_count} - социальные {data?.potreb_count + data?.potreb_soc_count} consumers (of which {data?.potreb_soc_count} are social facilities)
объекты)
</Row> </Row>
)} )}
{!isNil(data?.total_area) && ( {!isNil(data?.total_area) && (
<Row> <Row>
Общая площадь потребителей - {Math.ceil(data?.total_area)} кв. метров Total consumer area - {Math.ceil(data?.total_area)} sq. meters
</Row> </Row>
)} )}
{!isNil(data?.number_of_apartments) && ( {!isNil(data?.number_of_apartments) && (
<Row> <Row>
{data?.number_of_apartments} квартир {data?.number_of_apartments} apartments
</Row> </Row>
)} )}
{!isNil(data?.data_min_cooling_time) && !isNil(data?.min_cooling_time) && ( {!isNil(data?.data_min_cooling_time) && !isNil(data?.min_cooling_time) && (
<Row> <Row>
Быстрее всего остынет здание по The fastest cooling building is at
адресу {data?.data_min_cooling_time.building_address} ({data?.min_cooling_time} часов) address {data?.data_min_cooling_time.building_address} ({data?.min_cooling_time} hours)
</Row> </Row>
)} )}

@ -1,9 +1,9 @@
import { Button, Col, Divider, Modal, Popover, Row, Tooltip } from "antd"; import { Button, Popover } from "antd";
import {useSimulateAccident} from "../stores/useSimulateAccident.js";
import {Title} from "../components/Title.jsx";
import { AccidentSimulationModal } from "./AccidentSimulation/AccidentSimulationModal.jsx";
import { useState } from "react"; import { useState } from "react";
import { BiInfoCircle } from "react-icons/all.js"; import { BiInfoCircle } from "react-icons/all.js";
import { Title } from "../components/Title.jsx";
import { useSimulateAccident } from "../stores/useSimulateAccident.js";
import { AccidentSimulationModal } from "./AccidentSimulation/AccidentSimulationModal.jsx";
export const AccidentSimulationResults = () => { export const AccidentSimulationResults = () => {
const {selectedSourceConfig, setSelectedSourceConfig} = useSimulateAccident(); const {selectedSourceConfig, setSelectedSourceConfig} = useSimulateAccident();
@ -17,9 +17,9 @@ export const AccidentSimulationResults = () => {
return ( return (
<> <>
<div className='absolute bottom-[20px] left-[20px] text-grey z-10 bg-white-background rounded-xl p-3 text-center'> <div className='absolute bottom-[20px] left-[20px] text-grey z-10 bg-white-background rounded-xl p-3 text-center'>
<Title text={`Результаты моделирования аварии на ТП ${selectedSourceConfig?.sourceId}`}/> <Title text={`Results of Energy source failure simulation ${selectedSourceConfig?.sourceId}`}/>
<div className="flex justify-center flex-row gap-2"> <div className="flex justify-center flex-row gap-2">
<Button type="primary" onClick={stopSimulation}>Отменить</Button> <Button type="primary" onClick={stopSimulation}>Cancel</Button>
{!!pointId && ( {!!pointId && (
<Popover content={<AccidentSimulationModal id={pointId} />}> <Popover content={<AccidentSimulationModal id={pointId} />}>
<Button className="flex justify-center items-center" type="primary" onClick={() => setModalOpen(true)}> <Button className="flex justify-center items-center" type="primary" onClick={() => setModalOpen(true)}>

@ -25,27 +25,27 @@ ChartJS.register(
); );
const GRAPH_LABELS_MAP= { const GRAPH_LABELS_MAP= {
t_shap: "Температура воздуха", t_shap: "Air temperature",
fi_remont1_shap: "Замена стояков ХВС", fi_remont1_shap: "Replacement of cold water risers",
fi_remont2_shap: "Ремонт разводящих внутридомовых магистралей ХВС", fi_remont2_shap: "Repair of internal cold water mains",
fi_remont3_shap: "Замена стояков ГВС", fi_remont3_shap: "Replacement of hot water risers",
fi_remont4_shap: "Ремонт разводящих внутридомовых магистралей ГВС", fi_remont4_shap: "Repair of internal hot water mains",
fi_remont5_shap: "Ремонт стояков канализации", fi_remont5_shap: "Repair of sewer risers",
fi_remont6_shap: "Ремонт выпусков и сборных трубопроводов системы канализации", fi_remont6_shap: "Repair of sewer outlets and collector pipelines",
fi_remont7_shap: "Ремонт внутридомовых систем теплоснабжения (с заменой стояков)", fi_remont7_shap: "Repair of internal heating systems (with riser replacement)",
fi_remont8_shap: "Ремонт разводящих магистралей системы теплоснабжения", fi_remont8_shap: "Repair of heating mains",
total_area_shap: "Общая площадь", total_area_shap: "Total area",
fi_is_block_shap: "Материал - блочный", fi_is_block_shap: "Material - block",
fi_is_brick_shap: "Материал - кирпичный", fi_is_brick_shap: "Material - brick",
fi_is_panel_shap: "Материал - панельный", fi_is_panel_shap: "Material - panel",
building_wear_shap: "Износ", building_wear_shap: "Wear",
fi_is_monolit_shap: "Материал - монолитный", fi_is_monolit_shap: "Material - monolithic",
fi_energy_class_shap: "Класс энергоэффективности", fi_energy_class_shap: "Energy efficiency class",
fi_building_year_shap: "Год постройки", fi_building_year_shap: "Year of construction",
gvs_avg_heat_load_shap: "Средняя тепловая нагрузка ГВС", gvs_avg_heat_load_shap: "Average hot water heat load",
heating_heat_load_shap: "Тепловая нагрузка на отопление", heating_heat_load_shap: "Heating heat load",
gvs_fact_heat_load_shap: "Фактическая тепловая нагрузка ГВС", gvs_fact_heat_load_shap: "Actual hot water heat load",
ventilation_heat_load_shap: "Тепловая нагрузка на вентиляцию" ventilation_heat_load_shap: "Ventilation heat load"
}; };
export const PointChart = ({ point }) => { export const PointChart = ({ point }) => {
const { data: shapData } = useShap(point.id); const { data: shapData } = useShap(point.id);
@ -84,7 +84,7 @@ export const PointChart = ({ point }) => {
x: { x: {
title: { title: {
display: true, display: true,
text: 'Вклад в прогноз, %', text: 'Contribution to forecast, %',
}, },
grid: { grid: {
color: function(context) { color: function(context) {

@ -6,9 +6,9 @@ import { PointChart } from "./Chart.jsx";
const ChartHelp = () => { const ChartHelp = () => {
return ( return (
<div className="w-[200px]"> <div className="w-[200px]">
График показывает топ-15 факторов, которые оказывают наибольшее влияние на прогноз аварийности объекта.<br/><br/> The chart shows the top 15 factors that have the greatest impact on the failure forecast for the object.<br/><br/>
Факторы могут оказывать положительное или отрицательное влияние.<br/><br/> Factors can have a positive or negative impact.<br/><br/>
Чем больше влияния оказывает фактор на аварийность, тем ближе его значение к 100% (-100%). The stronger the factor's impact on failures, the closer its value is to 100% (-100%).
</div> </div>
) )
} }
@ -23,21 +23,21 @@ export const ChartModal = ({point}) => {
type="primary" type="primary"
onClick={() => setIsOpened(false)} onClick={() => setIsOpened(false)}
> >
Закрыть Close
</Button>, </Button>,
] ]
} }
return ( return (
<div className="flex items-center"> <div className="flex items-center">
<Tooltip title="Влияние факторов на прогноз"> <Tooltip title="Impact of factors on forecast">
<Button className="flex justify-center items-center h-6 ml-1 mb-1 p-2" type="primary" onClick={() => setIsOpened(true)}> <Button className="flex justify-center items-center h-6 ml-1 mb-1 p-2" type="primary" onClick={() => setIsOpened(true)}>
Влияние факторов на прогноз Impact of factors on forecast
</Button> </Button>
</Tooltip> </Tooltip>
<Modal <Modal
open={isOpened} open={isOpened}
title="Вклад факторов в прогноз аварийности" title="Contribution of factors to failure forecast"
onCancel={() => setIsOpened(false)} onCancel={() => setIsOpened(false)}
width={800} width={800}
footer={getFooter()} footer={getFooter()}
@ -47,7 +47,7 @@ export const ChartModal = ({point}) => {
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Row className={twMerge("p-1")}> <Row className={twMerge("p-1")}>
<Col className={"font-semibold"} span={12}> <Col className={"font-semibold"} span={12}>
Адрес точки: Point address:
</Col> </Col>
<Col span={12}>{point.building_address}</Col> <Col span={12}>{point.building_address}</Col>
</Row> </Row>
@ -60,7 +60,7 @@ export const ChartModal = ({point}) => {
placement="leftBottom" placement="leftBottom"
color="#ffffff" color="#ffffff"
> >
<Button type="text" className="text-[#1890FF] p-0">Как читать график?</Button> <Button type="text" className="text-[#1890FF] p-0">How to read the chart?</Button>
</Popover> </Popover>
</div> </div>

@ -3,7 +3,7 @@ import {UploadOutlined} from "@ant-design/icons";
export const ImportDataButton = ({onClick}) => { export const ImportDataButton = ({onClick}) => {
return <div className='absolute top-[20px] left-[20px]'> return <div className='absolute top-[20px] left-[20px]'>
<Tooltip title='Импорт данных' placement='right'> <Tooltip title='Data import' placement='right'>
<Button <Button
type="primary" type="primary"
icon={<UploadOutlined />} icon={<UploadOutlined />}

@ -67,8 +67,8 @@ const Uploader = ({text, dataType, onSuccess, onError}) => {
} }
const getMessage = () => { const getMessage = () => {
if (isInitialUploading) return 'Импорт данных' if (isInitialUploading) return 'Data import'
if (isFinished) return 'Импорт данных завершен' if (isFinished) return 'Data import completed'
return uploadData.description return uploadData.description
} }
@ -87,7 +87,7 @@ const Uploader = ({text, dataType, onSuccess, onError}) => {
return <div> return <div>
<div className='space-x-3'> <div className='space-x-3'>
<Tooltip title={'Перезаписать данные'}> <Tooltip title={'Overwrite data'}>
<Checkbox checked={shouldRefill} onChange={e => setShouldRefill(e.target.checked)}/> <Checkbox checked={shouldRefill} onChange={e => setShouldRefill(e.target.checked)}/>
</Tooltip> </Tooltip>
<Upload <Upload
@ -103,7 +103,7 @@ const Uploader = ({text, dataType, onSuccess, onError}) => {
type="text" type="text"
onClick={onTemplateDownload} onClick={onTemplateDownload}
> >
Скачать шаблон Download template
</Button> </Button>
</div> </div>
{getStatusInfo()} {getStatusInfo()}
@ -167,7 +167,7 @@ export const ImportDataModal = ({onClose}) => {
const getMessage = () => { const getMessage = () => {
if (isInitialAnalysisStarting) return 'Начало анализа' if (isInitialAnalysisStarting) return 'Начало анализа'
if (isFinished) return 'Анализ данных завершен' if (isFinished) return 'Data analysis completed'
return uploadData.description return uploadData.description
} }
@ -187,24 +187,24 @@ export const ImportDataModal = ({onClose}) => {
return ( return (
<Modal <Modal
open={true} open={true}
title="Импорт данных" title="Data import"
width={400} width={400}
footer={null} footer={null}
onCancel={onClose} onCancel={onClose}
> >
<div className='text-center space-y-3'> <div className='text-center space-y-3'>
<Alert <Alert
message="Обращаем ваше внимание, что импорт в зависимости от размера входных данных может занимать значительное время (до 10 мин)" message="Please note that import time can be significant (up to 10 minutes) depending on the size of the input data."
type="warning" type="warning"
className={'mb-5'} className={'mb-5'}
showIcon showIcon
closable closable
/> />
<Uploader dataType={'odpu'} text={'Выбрать файл с ОДПУ'} onSuccess={handleUploadSuccess} onError={handleUploadError}/> <Uploader dataType={'odpu'} text={'Select ODPU file'} onSuccess={handleUploadSuccess} onError={handleUploadError}/>
<Uploader dataType={'asupr'} text={'Выбрать файл с АСУПР'} onSuccess={handleUploadSuccess} onError={handleUploadError} /> <Uploader dataType={'asupr'} text={'Select ASUPR file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
<Uploader dataType={'moek_scheme'} text={'Выбрать файл с МОЭК'} onSuccess={handleUploadSuccess} onError={handleUploadError} /> <Uploader dataType={'moek_scheme'} text={'Select MOEK file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
<Uploader dataType={'events'} text={'Выбрать файл с событиями'} onSuccess={handleUploadSuccess} onError={handleUploadError} /> <Uploader dataType={'events'} text={'Select events file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
<Uploader dataType={'houses'} text={'Выбрать файл с домами'} onSuccess={handleUploadSuccess} onError={handleUploadError} /> <Uploader dataType={'houses'} text={'Select houses file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
<Button <Button
key="start-upload" key="start-upload"
className='mt-5' className='mt-5'
@ -213,10 +213,10 @@ export const ImportDataModal = ({onClose}) => {
loading={isInitialAnalysisStarting} loading={isInitialAnalysisStarting}
disabled={hasUploadError || isLoading} disabled={hasUploadError || isLoading}
> >
Начать анализ данных Start data analysis
</Button> </Button>
{getStatusInfo()} {getStatusInfo()}
{isError && <p className='text-red-600'>Произошла ошибка</p>} {isError && <p className='text-red-600'>An error occurred</p>}
</div> </div>
</Modal> </Modal>
); );

@ -70,9 +70,9 @@ export function Legend() {
{ {
consumer_filter ? <LegendColorRampItem consumer_filter ? <LegendColorRampItem
colors={consumerColors} colors={consumerColors}
name="Потребитель" name="Consumer"
desc={consumer_filter.key.includes("prob") ? "склонность к аварийности" : consumer_filter.key.includes("cooling_time") ? "время остывания, ч" : "приоритет здания"} desc={consumer_filter.key.includes("prob") ? "failure likelihood" : consumer_filter.key.includes("cooling_time") ? "cooling time, h" : "building priority"}
/> : <LegendPointItem name="Потребитель"/> /> : <LegendPointItem name="Consumer"/>
} }
</Checkbox> </Checkbox>
@ -85,9 +85,9 @@ export function Legend() {
{ {
source_filter ? <LegendColorRampItem source_filter ? <LegendColorRampItem
colors={sourceColors} colors={sourceColors}
name="Источник" name="Source"
desc={'склонность к аварийности'} desc={'failure likelihood'}
/> : <LegendPointItem name="Источник"/> /> : <LegendPointItem name="Source"/>
} }
</Checkbox> </Checkbox>
@ -96,7 +96,7 @@ export function Legend() {
onChange={() => toggleVisibility(LAYER_IDS.dispatcher)} onChange={() => toggleVisibility(LAYER_IDS.dispatcher)}
checked={isVisible[LAYER_IDS.dispatcher]} checked={isVisible[LAYER_IDS.dispatcher]}
> >
<LegendPointItem name="Диспетчерская" imageSrc={dispIcon} /> <LegendPointItem name="Dispatch center" imageSrc={dispIcon} />
</Checkbox> </Checkbox>
</div> </div>
</div> </div>

@ -11,14 +11,14 @@ export const ConsumerParameterSelect = ({ disabled }) => {
return ( return (
<div> <div>
<Title text={"Показатель потребителя"} /> <Title text={"Energy consumer parameter"} />
<TreeSelect <TreeSelect
mode="tags" mode="tags"
style={{ style={{
width: "100%", width: "100%",
}} }}
placeholder="Выберите показатель" placeholder="Select parameter"
onChange={(key) => setConsumerFilter(key)} onChange={(key) => setConsumerFilter(key)}
treeData={CONSUMER_OPTIONS} treeData={CONSUMER_OPTIONS}
allowClear={true} allowClear={true}

@ -51,7 +51,7 @@ export const ConsumerParameterSlider = ({ disabled, isLoading }) => {
<> <>
{consumer_filter && range && ( {consumer_filter && range && (
<Slider <Slider
title={key.includes("prob") ? "Склонность к аварийности" : key.includes("cooling_time") ? "Время остывания, ч" : "Приоритет здания"} title={key.includes("prob") ? "Failure likelihood" : key.includes("cooling_time") ? "Cooling time, h" : "Building priority"}
value={[values[0], values[1]]} value={[values[0], values[1]]}
onAfterChange={handleAfterChange} onAfterChange={handleAfterChange}
min={range[0]} min={range[0]}

@ -6,8 +6,8 @@ import { useMemo } from "react";
const key = "potreb_type"; const key = "potreb_type";
const mapper = { const mapper = {
living_house: "Жилой дом", living_house: "Residential building",
soc_object: "Социальный объект" soc_object: "Social facility"
} }
export const ConsumerTypeSelect = ({ disabled }) => { export const ConsumerTypeSelect = ({ disabled }) => {
const { const {
@ -28,13 +28,13 @@ export const ConsumerTypeSelect = ({ disabled }) => {
}, [data]) }, [data])
return ( return (
<div> <div>
<Title text={"Тип потребителя"} /> <Title text={"Consumer type"} />
<Select <Select
style={{ style={{
width: "100%", width: "100%",
}} }}
placeholder="Выберите тип" placeholder="Select type"
onChange={(v, o) => setConsumerType(o)} onChange={(v, o) => setConsumerType(o)}
options={options} options={options}
allowClear={true} allowClear={true}

@ -25,13 +25,13 @@ export const EnergyClassSelect = ({ disabled }) => {
}, [data]) }, [data])
return ( return (
<div> <div>
<Title text={"Класс энергоэффективности"} /> <Title text={"Energy efficiency class"} />
<Select <Select
style={{ style={{
width: "100%", width: "100%",
}} }}
placeholder="Выберите тип" placeholder="Select type"
onChange={(v, o) => setEnergyClass(o)} onChange={(v, o) => setEnergyClass(o)}
options={options} options={options}
allowClear={true} allowClear={true}

@ -27,7 +27,7 @@ export const DzkhFilters = () => {
{(consumer_filter || source_filter) && <div className="flex items-center justify-end pt-4"> {(consumer_filter || source_filter) && <div className="flex items-center justify-end pt-4">
<div className="flex gap-2"> <div className="flex gap-2">
<Button onClick={() => clear()} type="secondary"> <Button onClick={() => clear()} type="secondary">
Сбросить фильтры Reset filters
</Button> </Button>
</div> </div>
</div>} </div>}

@ -4,7 +4,7 @@ import { useDzkhFilters } from "../../stores/useDzkhFilters.js";
const options = [{ const options = [{
value: "prob6", value: "prob6",
label: "Авария на ТП" label: "Energy source failure"
}]; }];
export const SourceParameterSelect = ({ disabled }) => { export const SourceParameterSelect = ({ disabled }) => {
@ -15,14 +15,14 @@ export const SourceParameterSelect = ({ disabled }) => {
return ( return (
<div> <div>
<Title text={"Показатель источника"} /> <Title text={"Energy source parameter"} />
<TreeSelect <TreeSelect
mode="tags" mode="tags"
style={{ style={{
width: "100%", width: "100%",
}} }}
placeholder="Выберите показатель" placeholder="Select parameter"
onChange={(key) => setSourceFilter(key)} onChange={(key) => setSourceFilter(key)}
treeData={options} treeData={options}
allowClear={true} allowClear={true}

@ -51,7 +51,7 @@ export const SourceParameterSlider = ({ disabled, isLoading }) => {
<> <>
{source_filter && range && ( {source_filter && range && (
<Slider <Slider
title={"Фильтр по показателю"} title={"Filter by parameter"}
value={[values[0], values[1]]} value={[values[0], values[1]]}
onAfterChange={handleAfterChange} onAfterChange={handleAfterChange}
min={range[0]} min={range[0]}

@ -25,13 +25,13 @@ export const WallMaterialSelect = ({ disabled }) => {
}, [data]) }, [data])
return ( return (
<div> <div>
<Title text={"Материал стен"} /> <Title text={"Wall material"} />
<Select <Select
style={{ style={{
width: "100%", width: "100%",
}} }}
placeholder="Выберите тип" placeholder="Select type"
onChange={(v, o) => setWallMaterial(o)} onChange={(v, o) => setWallMaterial(o)}
options={options} options={options}
allowClear={true} allowClear={true}

@ -16,7 +16,7 @@ export const WeatherSlider = ({ disabled, fullRange, isLoading }) => {
return ( return (
<div className="absolute w-[200px] top-[20px] right-[20px] text-xs text-grey z-10 bg-white-background rounded-xl p-3 space-y-3"> <div className="absolute w-[200px] top-[20px] right-[20px] text-xs text-grey z-10 bg-white-background rounded-xl p-3 space-y-3">
<Slider <Slider
title={"Температура воздуха на улице"} title={"Outdoor air temperature"}
value={value} value={value}
onAfterChange={setValue} onAfterChange={setValue}
min={range[0]} min={range[0]}

@ -18,7 +18,7 @@ export const ExportButton = ({ provider }) => {
}; };
return ( return (
<Tooltip title="Скачать данные"> <Tooltip title="Download data">
<Button <Button
onClick={handleExport} onClick={handleExport}
loading={startExport} loading={startExport}

@ -32,7 +32,7 @@ const ToggleFullScreenButton = () => {
return ( return (
<Tooltip <Tooltip
title={fullScreen ? "Свернуть" : "Раскрыть на полный экран"} title={fullScreen ? "Collapse" : "Expand to full screen"}
placement={"topRight"} placement={"topRight"}
open={hover} open={hover}
> >
@ -57,7 +57,7 @@ export const HeaderWrapper = ({
return ( return (
<div className={"flex items-center w-full justify-between"}> <div className={"flex items-center w-full justify-between"}>
<div className={classes?.leftColumn}> <div className={classes?.leftColumn}>
<span className="py-[5px]">Таблица атрибутов</span> <span className="py-[5px]">Attribute table</span>
{leftColumn} {leftColumn}
</div> </div>
<div className={classes?.rightColumn}> <div className={classes?.rightColumn}>

@ -60,7 +60,7 @@ export const Table = React.memo(
"table__wrapper", "table__wrapper",
tableState.fullScreen && "table__wrapper__fullScreen" tableState.fullScreen && "table__wrapper__fullScreen"
)} )}
locale={{ emptyText: <Empty description="Нет данных" /> }} locale={{ emptyText: <Empty description="No data" /> }}
pagination={{ pagination={{
pageSize, pageSize,
current: page, current: page,

@ -1,9 +1,9 @@
import {tempMapper} from "../../config"; import { useEffect, useMemo } from "react";
import {useEffect, useMemo} from "react"; import { useGetRegions } from "../../components/RegionSelect.jsx";
import {useGetRegions} from "../../components/RegionSelect.jsx"; import { tempMapper } from "../../config";
import {useTable} from "../../stores/useTable.js"; import { useWeatherFilter } from "../../dzkh-features/WeatherSlider/useWeatherFilter.js";
import useLocalStorage from "../../hooks/useLocalStorage.js"; import useLocalStorage from "../../hooks/useLocalStorage.js";
import {useWeatherFilter} from "../../dzkh-features/WeatherSlider/useWeatherFilter.js"; import { useTable } from "../../stores/useTable.js";
export const useColumns = (key) => { export const useColumns = (key) => {
const { data: regions } = useGetRegions(); const { data: regions } = useGetRegions();
@ -18,7 +18,7 @@ export const useColumns = (key) => {
const defaultColumns = useMemo(() => { const defaultColumns = useMemo(() => {
return [ return [
{ {
title: "Адрес", title: "Address",
dataIndex: "building_address", dataIndex: "building_address",
key: "building_address", key: "building_address",
width: "120px", width: "120px",
@ -27,7 +27,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Номер ТП", title: "TP number",
dataIndex: "tp_number", dataIndex: "tp_number",
key: "tp_number", key: "tp_number",
width: "120px", width: "120px",
@ -36,7 +36,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Номер ОДС", title: "Dispatcher center number",
dataIndex: "ods_number", dataIndex: "ods_number",
key: "ods_number", key: "ods_number",
width: "120px", width: "120px",
@ -45,7 +45,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Телефон ОДС", title: "Dispatcher phone",
dataIndex: "phone_number", dataIndex: "phone_number",
key: "phone_number", key: "phone_number",
width: "120px", width: "120px",
@ -54,7 +54,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Отсутствие отопления в доме", title: "No heating in the building",
dataIndex: `prob1_${tempMapper[temperature]}`, dataIndex: `prob1_${tempMapper[temperature]}`,
key: "prob1", key: "prob1",
width: "120px", width: "120px",
@ -63,7 +63,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Протечка труб в подъезде", title: "Leaking pipes in the entrance",
dataIndex: `prob2_${tempMapper[temperature]}`, dataIndex: `prob2_${tempMapper[temperature]}`,
key: "prob2", key: "prob2",
width: "120px", width: "120px",
@ -72,7 +72,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Температура в квартире ниже нормативной", title: "Apartment temperature below standard",
dataIndex: `prob3_${tempMapper[temperature]}`, dataIndex: `prob3_${tempMapper[temperature]}`,
key: "prob3", key: "prob3",
width: "120px", width: "120px",
@ -81,7 +81,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Температура в помещении общего пользования ниже нормативной", title: "Common area temperature below standard",
dataIndex: `prob4_${tempMapper[temperature]}`, dataIndex: `prob4_${tempMapper[temperature]}`,
key: "prob4", key: "prob4",
width: "120px", width: "120px",
@ -90,7 +90,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Течь в системе отопления", title: "Leak in the heating system",
dataIndex: `prob5_${tempMapper[temperature]}`, dataIndex: `prob5_${tempMapper[temperature]}`,
key: "prob5", key: "prob5",
width: "120px", width: "120px",
@ -99,7 +99,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Авария на ТП", title: "Energy source failure",
dataIndex: `prob6_${tempMapper[temperature]}`, dataIndex: `prob6_${tempMapper[temperature]}`,
key: "prob6", key: "prob6",
width: "120px", width: "120px",
@ -109,7 +109,7 @@ export const useColumns = (key) => {
}, },
{ {
title: "Время остывания, ч", title: "Cooling time, h",
dataIndex: `cooling_time_${tempMapper[temperature]}`, dataIndex: `cooling_time_${tempMapper[temperature]}`,
key: "cooling_time", key: "cooling_time",
width: "120px", width: "120px",
@ -118,7 +118,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Приоритет здания", title: "Building priority",
dataIndex: `priority_${tempMapper[temperature]}`, dataIndex: `priority_${tempMapper[temperature]}`,
key: "priority", key: "priority",
width: "120px", width: "120px",
@ -127,7 +127,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Материал стен", title: "Wall material",
dataIndex: "wall_materials", dataIndex: "wall_materials",
key: "wall_materials", key: "wall_materials",
width: "120px", width: "120px",
@ -136,7 +136,7 @@ export const useColumns = (key) => {
showSorterTooltip: false, showSorterTooltip: false,
}, },
{ {
title: "Класс энергоэффективности", title: "Energy efficiency class",
dataIndex: "fi_energy_class", dataIndex: "fi_energy_class",
key: "fi_energy_class", key: "fi_energy_class",
width: "120px", width: "120px",

@ -1479,7 +1479,7 @@ kdbush@^3.0.0:
resolved "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz" resolved "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz"
integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew== integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==
keycloak-js@>=9.0.2, keycloak-js@22.0.5: keycloak-js@>=9.0.2:
version "22.0.5" version "22.0.5"
resolved "https://registry.npmjs.org/keycloak-js/-/keycloak-js-22.0.5.tgz" resolved "https://registry.npmjs.org/keycloak-js/-/keycloak-js-22.0.5.tgz"
integrity sha512-a7ZwCZeHl8tpeJBy102tZtAnHslDUOA1Nf/sHNF3HYLchKpwoDuaitwIUiS2GnNUe+tlNKLlCqZS+Mi5K79m1w== integrity sha512-a7ZwCZeHl8tpeJBy102tZtAnHslDUOA1Nf/sHNF3HYLchKpwoDuaitwIUiS2GnNUe+tlNKLlCqZS+Mi5K79m1w==

Loading…
Cancel
Save