81 lines
2.7 KiB
JavaScript
81 lines
2.7 KiB
JavaScript
import React from 'react';
|
|
|
|
export default function NodeCard({ meta, weight, params, onWeightChange, onParamsChange }) {
|
|
const enabled = (weight ?? 0) > 0;
|
|
|
|
return (
|
|
<div className="node-card" style={{ opacity: enabled ? 1 : 0.6 }}>
|
|
<div className="node-card-header">
|
|
<label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
<input
|
|
type="checkbox"
|
|
checked={enabled}
|
|
onChange={(e) => onWeightChange(e.target.checked ? (weight || 1) : 0)}
|
|
/>
|
|
<span>{meta.label}</span>
|
|
</label>
|
|
</div>
|
|
<div className="node-card-body">
|
|
<div className="weight-row">
|
|
<span style={{ width: 50, fontSize: 12, color: '#9ca3af' }}>가중치</span>
|
|
<input
|
|
type="range" min="0" max="3" step="0.1"
|
|
value={weight ?? 0}
|
|
disabled={!enabled}
|
|
onChange={(e) => onWeightChange(parseFloat(e.target.value))}
|
|
style={{ flex: 1 }}
|
|
/>
|
|
<span style={{ width: 32, textAlign: 'right', fontSize: 12 }}>{(weight ?? 0).toFixed(1)}</span>
|
|
</div>
|
|
{Object.entries(meta.param_schema?.properties || {}).map(([key, prop]) => (
|
|
<ParamRow
|
|
key={key}
|
|
paramKey={key}
|
|
prop={prop}
|
|
value={params?.[key] ?? meta.default_params?.[key]}
|
|
disabled={!enabled}
|
|
onChange={(v) => onParamsChange({ ...params, [key]: v })}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function ParamRow({ paramKey, prop, value, disabled, onChange }) {
|
|
const type = prop.type;
|
|
if (type === 'integer' || type === 'number') {
|
|
return (
|
|
<div className="param-row">
|
|
<span style={{ width: 100, fontSize: 12 }}>{paramKey}</span>
|
|
<input
|
|
type="number"
|
|
min={prop.minimum} max={prop.maximum}
|
|
step={type === 'integer' ? 1 : 0.1}
|
|
value={value ?? ''}
|
|
disabled={disabled}
|
|
onChange={(e) => onChange(type === 'integer' ? parseInt(e.target.value, 10) : parseFloat(e.target.value))}
|
|
style={{ width: 80 }}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
if (type === 'boolean') {
|
|
return (
|
|
<div className="param-row">
|
|
<label>
|
|
<input type="checkbox" checked={!!value} disabled={disabled}
|
|
onChange={(e) => onChange(e.target.checked)} />
|
|
<span style={{ marginLeft: 6, fontSize: 12 }}>{paramKey}</span>
|
|
</label>
|
|
</div>
|
|
);
|
|
}
|
|
// object/array는 MVP에서 read-only JSON 표시 (RsRating의 weights 등)
|
|
return (
|
|
<div className="param-row" style={{ fontSize: 11, color: '#9ca3af' }}>
|
|
{paramKey}: <code>{JSON.stringify(value)}</code>
|
|
</div>
|
|
);
|
|
}
|