Spaces:
Sleeping
Sleeping
Download frontend/src/components/analysis/StreamSelector.tsx from DAG-UPB/HeatTransPlan: direct link, hf CLI and curl.
- Browser
- Download file 4.16 kB
-
https://huggingface.co/spaces/DAG-UPB/HeatTransPlan/resolve/main/frontend/src/components/analysis/StreamSelector.tsx
- Command line
-
hf download hf://spaces/DAG-UPB/HeatTransPlan/frontend/src/components/analysis/StreamSelector.tsx
-
curl -L -o StreamSelector.tsx https://huggingface.co/spaces/DAG-UPB/HeatTransPlan/resolve/main/frontend/src/components/analysis/StreamSelector.tsx
4.16 kB
| /** 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> | |
| ); | |
| } | |