feat(screener): GateNodeCard for hygiene gate
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
import React, { memo, useState } from 'react';
|
||||||
|
import { Handle, Position } from '@xyflow/react';
|
||||||
|
|
||||||
|
function ParamField({ name, schema, value, onChange }) {
|
||||||
|
if (schema?.type === 'boolean') {
|
||||||
|
return (
|
||||||
|
<label className="canvas-param-field">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={!!value}
|
||||||
|
onChange={(e) => onChange(name, e.target.checked)}
|
||||||
|
/>
|
||||||
|
<span>{schema.label || name}</span>
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<label className="canvas-param-field">
|
||||||
|
<span>{schema?.label || name}</span>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={value ?? schema?.default ?? 0}
|
||||||
|
step={schema?.step ?? 1}
|
||||||
|
onChange={(e) => onChange(name, Number(e.target.value))}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function GateNodeCard({ data }) {
|
||||||
|
const { meta, params, onChange, description } = data;
|
||||||
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
|
||||||
|
const update = (key, v) => onChange({ ...params, [key]: v });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="canvas-node canvas-node--gate">
|
||||||
|
<Handle type="target" position={Position.Left} isConnectable={false} />
|
||||||
|
<div className="canvas-node-title">
|
||||||
|
<span className="canvas-node-icon">🛡️</span>
|
||||||
|
<span>{meta?.label || '위생 게이트'}</span>
|
||||||
|
{description && (
|
||||||
|
<span className="canvas-node-info" title={description}>ⓘ</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="canvas-node-summary">통과해야 점수 단계 진입</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="canvas-node-expand"
|
||||||
|
onClick={() => setExpanded((v) => !v)}
|
||||||
|
>
|
||||||
|
{expanded ? '▴ 파라미터' : '▾ 파라미터'}
|
||||||
|
</button>
|
||||||
|
{expanded && (
|
||||||
|
<div className="canvas-node-params">
|
||||||
|
{Object.entries(meta?.param_schema || {}).map(([key, schema]) => (
|
||||||
|
<ParamField
|
||||||
|
key={key}
|
||||||
|
name={key}
|
||||||
|
schema={schema}
|
||||||
|
value={params?.[key]}
|
||||||
|
onChange={update}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<Handle type="source" position={Position.Right} isConnectable={false} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(GateNodeCard);
|
||||||
Reference in New Issue
Block a user