HeatTransPlan / frontend /src /components /process /StreamEditor.tsx
drzg15's picture
Initial code commit with LFS for binaries
c993983
import type { Stream, StreamType } from '../../types/stream';
import './StreamEditor.css';
interface Props {
id?: string;
stream: Stream;
onChange: (updated: Stream) => void;
onDelete: () => void;
}
const ALL_VARS = [
'Tin',
'Tout',
'ṁ',
'cp',
'CP',
'Water Content In',
'Water Content Out',
'Density',
'Pressure',
];
const DEFAULT_VARS: Record<StreamType, string[]> = {
product: ['Tin', 'Tout', 'ṁ', 'cp'],
steam: ['Tin', 'ṁ'],
water: ['Tin', 'ṁ', 'Water Content In', 'Water Content Out'],
air: ['Tin', 'ṁ'],
};
const STREAM_TYPES: StreamType[] = ['product', 'steam', 'air', 'water'];
export default function StreamEditor({ id, stream, onChange, onDelete }: Props) {
const displayVars = stream.display_vars?.length
? stream.display_vars
: DEFAULT_VARS[stream.type] || DEFAULT_VARS.product;
const update = (partial: Partial<Stream>) => {
onChange({ ...stream, ...partial });
};
const handleTypeChange = (type: StreamType) => {
update({
type,
display_vars: DEFAULT_VARS[type],
});
};
const toggleVar = (varName: string) => {
const current = [...displayVars];
const idx = current.indexOf(varName);
if (idx >= 0) {
current.splice(idx, 1);
} else {
current.push(varName);
}
update({ display_vars: current });
};
const updateValue = (key: string, value: string) => {
const sv = { ...(stream.stream_values || {}) };
sv[key] = value;
update({ stream_values: sv });
};
return (
<div className="se-card" id={id}>
{/* Header row */}
<div className="se-header">
<input
type="text"
className="se-name"
value={stream.name}
onChange={(e) => update({ name: e.target.value })}
placeholder="Stream name"
/>
<select
className="se-type"
value={stream.type}
onChange={(e) => handleTypeChange(e.target.value as StreamType)}
>
{STREAM_TYPES.map((t) => (
<option key={t} value={t}>
{t}
</option>
))}
</select>
<button className="btn btn-sm" onClick={onDelete} title="Delete stream">
</button>
</div>
{/* Variable selector */}
<div className="se-var-selector">
{ALL_VARS.map((v) => {
const isSelected = displayVars.includes(v);
return (
<button
key={v}
className={`se-var-pill ${isSelected ? 'active' : ''}`}
onClick={() => toggleVar(v)}
>
{v}
</button>
);
})}
</div>
{/* Value inputs */}
<div className="se-values">
{displayVars.map((v) => (
<div key={v} className="se-value-field">
<label>{v}</label>
<input
type="text"
value={stream.stream_values?.[v] || ''}
onChange={(e) => updateValue(v, e.target.value)}
placeholder="—"
/>
</div>
))}
</div>
</div>
);
}