Files
fusion/packages/dashboard/app/components/ProjectNodeSelector.tsx
gsxdsm a2e96b132a feat(i18n): round-2 sweep — 488 residual strings migrated, markup fidelity restored (#1352)
- 51 fix agents covered every dirty batch from the round-1 verifiers:
  helper-function labels (roles, statuses, relative time), constant
  label maps (SETTINGS_SECTIONS, PROVIDER_INFO, EVENT_TYPE_LABELS),
  TUI help overlay + tab labels, toasts, placeholders, aria-labels
- Inline markup flattened by round 1 restored with <Trans>
  (DbCorruptionBanner storage-docs link, UpdateAvailableBanner code chip)
- Catalogs merged: +527 en keys across 5 locales; CLI bundles + app
  locale tree regenerated (6 locales)
- All 23 sweep-caused test regressions fixed: delta vs the clean-main
  baseline is now zero (remaining 4 local failures reproduce identically
  on origin/main; CI-green upstream)
- typecheck/lint clean; TUI 82/82, core locale 9/9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 20:52:44 -07:00

56 lines
1.8 KiB
TypeScript

import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import type { NodeInfo } from "../api";
import "./ProjectNodeSelector.css";
interface ProjectNodeSelectorProps {
projectId: string;
currentNodeId?: string;
onSelect: (nodeId: string | null) => void;
nodes: NodeInfo[];
disabled?: boolean;
}
export function ProjectNodeSelector({
projectId,
currentNodeId,
onSelect,
nodes,
disabled = false,
}: ProjectNodeSelectorProps) {
const { t } = useTranslation("app");
const sortedNodes = useMemo(() => {
return [...nodes].sort((a, b) => a.name.localeCompare(b.name));
}, [nodes]);
const selectedValue = currentNodeId ?? "";
return (
<label className="project-node-selector" htmlFor={`project-node-selector-${projectId}`}>
<span className="project-node-selector__label">{t("nodes.runtimeNodeLabel", "Runtime Node")}</span>
<select
className="select"
id={`project-node-selector-${projectId}`}
value={selectedValue}
onChange={(event) => {
const value = event.target.value;
onSelect(value ? value : null);
}}
disabled={disabled}
>
<option value="">{t("nodes.autoAssignment", "Auto (no assignment)")}</option>
{sortedNodes.map((node) => (
<option
key={node.id}
value={node.id}
title={t("nodes.statusTitle", "Status: {{status}}", { status: node.status })}
className={node.status === "offline" || node.status === "error" ? "project-node-selector__option--dim" : ""}
>
{t("nodes.nodeLabel", "{{name}} ({{type}}) — {{status}}", { name: node.name, type: node.type, status: node.status })}
</option>
))}
</select>
</label>
);
}