diff --git a/src/entities/current/types.ts b/src/entities/current/types.ts
index bfa31cf..bf97b7c 100644
--- a/src/entities/current/types.ts
+++ b/src/entities/current/types.ts
@@ -1,7 +1,7 @@
export type CurrentItem = {
edge: string;
tag: string;
- value: number;
+ value: number | null;
createdAt: string;
updatedAt: string;
time: string;
diff --git a/src/features/edge-detail/components/ArchiveView.tsx b/src/features/edge-detail/components/ArchiveView.tsx
index 9c5909d..ce4dbfd 100644
--- a/src/features/edge-detail/components/ArchiveView.tsx
+++ b/src/features/edge-detail/components/ArchiveView.tsx
@@ -5,7 +5,7 @@ import { CalendarDays, CalendarClock, Check, ChevronDown, Clock3, DatabaseZap, S
import type { CurrentItem } from '../../../entities/current/types';
import { HistoryChart } from '../../../features/history-chart/HistoryChart';
import { RANGE_PRESETS, createRange, type DateRangeState } from '../../../features/history/dateRange';
-import { toIsoFromInput } from '../../../utils/format';
+import { formatNumber, toIsoFromInput } from '../../../utils/format';
import type { HistoryGranularity } from '../../../utils/historyGranularity';
type ArchiveViewProps = {
@@ -191,7 +191,7 @@ export function ArchiveView({
{label !== item.tag ? {item.tag} : null}
- {item.value.toLocaleString('ru-RU', { maximumFractionDigits: item.precision ?? 3 })}
+ {formatNumber(item.value)}
{selected ? : null}
diff --git a/src/features/electrical-schematics/ElectricalNode.tsx b/src/features/electrical-schematics/ElectricalNode.tsx
index 3b51f56..bf9dfb7 100644
--- a/src/features/electrical-schematics/ElectricalNode.tsx
+++ b/src/features/electrical-schematics/ElectricalNode.tsx
@@ -29,8 +29,8 @@ export function ElectricalNode({ liveValues, node, ownerEdgeId }: ElectricalNode
? getLiveValue(liveValues, node.edgeId || ownerEdgeId, node.tagId)
: getLiveValue(liveValues, bindingEdgeId, bindings?.stateTagId);
const alarmValue = node.kind === 'decoration' ? getLiveValue(liveValues, bindingEdgeId, bindings?.alarmTagId) : undefined;
- const alarmActive = Boolean(alarmValue && Number(alarmValue.value) !== 0);
- const stateActive = Boolean(mainValue && Number(mainValue.value) !== 0);
+ const alarmActive = Boolean(alarmValue && alarmValue.value !== null && alarmValue.value !== 0);
+ const stateActive = Boolean(mainValue && mainValue.value !== null && mainValue.value !== 0);
const title = getNodeTitle(node, mainValue);
const style: CSSProperties = {
left: node.position.x,
diff --git a/src/utils/format.ts b/src/utils/format.ts
index 2f27483..e5e81f2 100644
--- a/src/utils/format.ts
+++ b/src/utils/format.ts
@@ -1,7 +1,7 @@
/** Форматирует числовое значение показателя для карточек и мини-плиток. */
-export function formatNumber(value: number): string {
- if (!Number.isFinite(value)) {
- return '-';
+export function formatNumber(value: number | null): string {
+ if (value === null || !Number.isFinite(value)) {
+ return '—';
}
return new Intl.NumberFormat('ru-RU', {
diff --git a/src/utils/metricStatus.ts b/src/utils/metricStatus.ts
index 10be0bd..6c246d4 100644
--- a/src/utils/metricStatus.ts
+++ b/src/utils/metricStatus.ts
@@ -16,8 +16,9 @@ function isConfiguredLimit(value: number | null): value is number {
export function getMetricStatus(item: CurrentItem, now = Date.now()): MetricStatusInfo {
const measuredAt = new Date(item.time).getTime();
const ageSeconds = Number.isFinite(measuredAt) ? Math.max(0, Math.round((now - measuredAt) / 1000)) : Number.POSITIVE_INFINITY;
- const belowMin = isConfiguredLimit(item.min) && item.value < item.min;
- const aboveMax = isConfiguredLimit(item.max) && item.value > item.max;
+ const value = item.value;
+ const belowMin = isConfiguredLimit(value) && isConfiguredLimit(item.min) && value < item.min;
+ const aboveMax = isConfiguredLimit(value) && isConfiguredLimit(item.max) && value > item.max;
if (belowMin || aboveMax) {
return { status: 'critical', label: 'за пределами уставки', ageSeconds };