Spaces:
Sleeping
Sleeping
File size: 4,160 Bytes
c993983 d1439c7 c993983 70656b2 7c893d7 c993983 7c893d7 c993983 7c893d7 c993983 70656b2 c993983 70656b2 c993983 70656b2 7c893d7 70656b2 c993983 70656b2 c993983 7c893d7 c993983 7c893d7 c993983 7bdb397 c993983 7c893d7 c993983 70656b2 c993983 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /** StreamSelector — checkbox list of all streams grouped by subprocess. */
import { useEffect, useCallback } from 'react';
import { useProjectStore } from '../../store/projectStore';
import { useAnalysisStore } from '../../store/analysisStore';
import { getStreamInfo } from '../../utils/streamUtils';
import type { Stream } from '../../types/stream';
import ChartHelpButton from '../ui/ChartHelpButton';
import { useTranslation } from 'react-i18next';
export default function StreamSelector() {
const { t } = useTranslation();
const processes = useProjectStore((s) => s.state.processes);
const selectedStreams = useAnalysisStore((s) => s.selectedStreams);
const setSelectedStream = useAnalysisStore((s) => s.setSelectedStream);
// Initialize any streams that haven't been seen yet as "selected" by default
useEffect(() => {
const keysToEnable: string[] = [];
processes.forEach((proc, pi) => {
(proc.streams ?? []).forEach((_s: Stream, si: number) => {
const key = `stream_${pi}_${si}`;
// If it's not even in the map yet, we mark it as "to be enabled"
if (selectedStreams[key] === undefined) {
keysToEnable.push(key);
}
});
});
if (keysToEnable.length > 0) {
// Direct merge into store to avoid overwriting existing selections
const next = { ...selectedStreams };
keysToEnable.forEach(k => next[k] = true);
useAnalysisStore.setState({ selectedStreams: next });
}
}, [processes, selectedStreams]);
const handleToggle = useCallback(
(key: string) => {
setSelectedStream(key, !selectedStreams[key]);
},
[selectedStreams, setSelectedStream],
);
if (!processes.length) {
return <div className="pa-info-box">{t('analysis.messages.no_processes')}</div>;
}
return (
<div className="pa-panel">
<h4
className="pa-panel-title"
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}
>
<span style={{ display: 'flex', alignItems: 'center' }}>
{t('stream_selector.title')}
<ChartHelpButton inline title={t('stream_selector.title')} description={t('stream_selector.help_desc')} />
</span>
</h4>
<div className="pa-stream-list">
{processes.map((proc, pi) => {
const streams = proc.streams ?? [];
if (streams.length === 0) return null;
const procName = proc.name || `${t('stream_selector.subprocess')} ${pi + 1}`;
return (
<div key={pi} className="pa-stream-group">
<div className="pa-stream-group-title">{procName}</div>
{streams.map((stream: Stream, si: number) => {
const key = `stream_${pi}_${si}`;
const checked = selectedStreams[key] ?? true;
const info = getStreamInfo(stream);
const streamName = stream.name || `${t('stream_selector.stream')} ${si + 1}`;
const parts: string[] = [];
if (info.tin !== null) parts.push(`Tin:${info.tin}°C`);
if (info.tout !== null) parts.push(`Tout:${info.tout}°C`);
if (info.CP !== null) parts.push(`CP:${info.CP.toFixed(2)}`);
if (info.Q !== null) parts.push(`Q:${info.Q.toFixed(2)} kW`);
if (info.type) parts.push(info.type.includes('Hot') ? '🔴' : '🔵');
return (
<label key={key} className="pa-stream-item" title={streamName}>
<input
type="checkbox"
checked={checked}
onChange={() => handleToggle(key)}
/>
<span className="pa-stream-name">{streamName}</span>
<span className="pa-stream-info">
{parts.length > 0 ? parts.join(' | ') : t('stream_selector.incomplete')}
</span>
</label>
);
})}
</div>
);
})}
</div>
</div>
);
}
|