164 lines
4.4 KiB
TypeScript
164 lines
4.4 KiB
TypeScript
import { type ScheduleNode } from "../../services/api";
|
|
import Icon from "../../components/common/Icon";
|
|
import { shortHash } from "./utils";
|
|
import { PYTHON_VERSION_OPTIONS, type NodeForm } from "./state/schedulesStore";
|
|
|
|
export function NodeInspector({
|
|
node,
|
|
form,
|
|
busy,
|
|
onChange,
|
|
onSave,
|
|
onDelete,
|
|
}: {
|
|
node: ScheduleNode;
|
|
form: NodeForm;
|
|
busy: boolean;
|
|
onChange: (form: NodeForm) => void;
|
|
onSave: () => void;
|
|
onDelete: () => void;
|
|
}) {
|
|
return (
|
|
<div className="schedule-inspector">
|
|
<section className="node-inspector-title">
|
|
<span className={`artifact-card__icon artifact-card__icon--${node.version.script_type}`}>
|
|
<Icon
|
|
name={node.version.script_type === "notebook" ? "notebook" : "python"}
|
|
size={17}
|
|
/>
|
|
</span>
|
|
<div>
|
|
<small>节点配置</small>
|
|
<strong>{node.node_key}</strong>
|
|
</div>
|
|
</section>
|
|
<section>
|
|
<h3>稳定版本</h3>
|
|
<div className="version-readonly">
|
|
<strong>{node.version.script_name}</strong>
|
|
<span>{node.version.version_label}</span>
|
|
<small>versions_id: {node.versions_id}</small>
|
|
<small>SHA-256: {shortHash(node.version.content_hash)}</small>
|
|
</div>
|
|
</section>
|
|
<section>
|
|
<h3>节点信息</h3>
|
|
<label>
|
|
<span>节点名称</span>
|
|
<input
|
|
value={form.nodeName}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
nodeName: event.target.value,
|
|
})}
|
|
/>
|
|
</label>
|
|
<div className="inspector-grid">
|
|
<label>
|
|
<span>超时(秒)</span>
|
|
<input
|
|
type="number"
|
|
min="1"
|
|
value={form.timeoutSeconds}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
timeoutSeconds: event.target.value,
|
|
})}
|
|
/>
|
|
</label>
|
|
<label>
|
|
<span>重试次数</span>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
max="10"
|
|
value={form.retryCount}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
retryCount: event.target.value,
|
|
})}
|
|
/>
|
|
</label>
|
|
</div>
|
|
<div className="inspector-grid">
|
|
<label>
|
|
<span>重试间隔(秒)</span>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
value={form.retryIntervalSec}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
retryIntervalSec: event.target.value,
|
|
})}
|
|
/>
|
|
</label>
|
|
<label>
|
|
<span>Python 版本</span>
|
|
<select
|
|
value={form.pythonVersion}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
pythonVersion: event.target.value as NodeForm["pythonVersion"],
|
|
})}
|
|
>
|
|
{PYTHON_VERSION_OPTIONS.map((option) => (
|
|
<option key={option} value={option}>
|
|
{option}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</label>
|
|
</div>
|
|
</section>
|
|
<section>
|
|
<h3>运行参数</h3>
|
|
<label>
|
|
<span>arguments_json</span>
|
|
<textarea
|
|
className="json-editor"
|
|
rows={5}
|
|
spellCheck={false}
|
|
value={form.argumentsJson}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
argumentsJson: event.target.value,
|
|
})}
|
|
/>
|
|
</label>
|
|
<label>
|
|
<span>env_refs_json</span>
|
|
<textarea
|
|
className="json-editor"
|
|
rows={4}
|
|
spellCheck={false}
|
|
value={form.envRefsJson}
|
|
onChange={(event) => onChange({
|
|
...form,
|
|
envRefsJson: event.target.value,
|
|
})}
|
|
/>
|
|
</label>
|
|
</section>
|
|
<div className="node-inspector-actions">
|
|
<button
|
|
className="inspector-primary-button"
|
|
type="button"
|
|
disabled={busy}
|
|
onClick={onSave}
|
|
>
|
|
保存节点
|
|
</button>
|
|
<button
|
|
className="inspector-danger-button"
|
|
type="button"
|
|
disabled={busy}
|
|
onClick={onDelete}
|
|
>
|
|
删除节点
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|