import { useTranslation } from "react-i18next";
import { TrackingRepoSelect, type TrackingRepoOption } from "../../TrackingRepoSelect";
import { SettingsToggleRow } from "../SettingsToggleRow";
import { SettingsHelpTip } from "../SettingsHelpTip";
import { SettingsSelectRow } from "../SettingsSelectRow";
import { SettingsTextRow } from "../SettingsTextRow";
import type { SectionBaseProps } from "./context";
export interface SourceControlSectionProps extends SectionBaseProps {
projectTrackingRepoOptions: TrackingRepoOption[];
projectTrackingRepoLoading: boolean;
projectTrackingRepoError: string | null;
}
/*
FNXC:SourceControl 2026-07-15-20:30:
Project source-control settings were split across two sections that neither named nor contained the topic: GitHub Tracking + the GitLab URL disclosure lived in "General · Project", while GitHub/GitLab authentication lived in "Merge". An operator wiring up GitLab had to visit both, and `gitlabEnabled` was writable from BOTH — two enable toggles for one key, so the last section saved won. This section is the single project-scoped home for GitHub/GitLab, which is what removes that duplicate rather than merely hiding it.
The GitLab URL block and the GitLab auth block are now ONE disclosure with ONE `gitlabEnabled` toggle in its summary. Both blocks were already governed by that same key (FN-7453), so merging them costs no behavior — the two toggles were always writing the same setting.
FNXC:SettingsScope 2026-07-15-20:30:
Rows on `gitlabEnabled`, `gitlabInstanceUrl`, `gitlabApiBaseUrl`, `gitlabAuthTokenType`, `gitlabAuthToken`, and `githubTrackingDefaultRepo` carry NO scope badge: every one of them is declared in BOTH `DEFAULT_GLOBAL_SETTINGS` and `DEFAULT_PROJECT_SETTINGS`, so a "project" badge would assert a scope the schema does not support. The section name ("Source Control · Project") carries the scope instead. The GitHub-only keys ARE project-only in the schema, so they keep their badge.
FNXC:SettingsStyling 2026-07-15-20:30:
Plain label+control+help rows render through the shared settings primitives. `githubAuthToken`/`gitlabAuthToken` use the primitive's `type: "password"` (which defaults `autocomplete="off"`) — previously these rows had to stay hand-rolled to avoid SettingsTextRow's hardcoded `type="text"` rendering a stored token in plain sight.
Rows that stay bespoke: the tracking-mode select (its help is TWO blocks, the second conditional on unrelated model settings — a descriptor `help` is one string), the tracking-repo select (custom widget), and the disclosure chrome itself.
FNXC:SettingsHelp 2026-07-15-22:40:
Staying off the primitive does NOT mean falling back to inline help. Both bespoke rows above render their copy through the same `SettingsHelpTip` as every migrated row, so the section shows one help idiom rather than a "?" on some rows and a paragraph on others. The tip hangs off the label line, so a custom control (or conditional, multi-part copy) is no obstacle — that is what its `ReactNode` children are for.
*/
export function SourceControlSection({ form, setForm, projectTrackingRepoOptions, projectTrackingRepoLoading, projectTrackingRepoError, }: SourceControlSectionProps) {
const { t } = useTranslation("app");
return (<>
{/*
FNXC:SettingsHelp 2026-07-15-22:40:
Both help strings ride in ONE tip rather than two inline ``s. They are the same row's help — what the mode does, and how the issue title is derived — and the descriptor-based rows beside this one already carry a "?", so leaving these inline made the section render two idioms side by side.
Two strings in one bubble (not two triggers) because an operator asking "what does this control do?" wants both answers at once; the second is a caveat on the first, not a separate topic.
This is what `SettingsHelpTip`'s `ReactNode` children buy: the trailing fragment stays CONDITIONAL on the summarization settings, which a single-string descriptor `help` could not express — the reason this row is still hand-rolled.
*/}
{t("settings.general.controlsWhetherNewlyCreatedTasksHaveGitHubIssue", " Controls whether newly created tasks have GitHub issue tracking enabled by default. Individual tasks can still override this from the task detail modal. ")}
{/*
FNXC:SettingsGeneral 2026-06-22-03:20:
Tracking-issue helper copy. The FN-6771 JSX→t() extraction left a raw HTML
entity ("'") in this default string. As a t() argument the string is a
plain JS value (not JSX-decoded), so the entity rendered verbatim as the
literal "'" instead of an apostrophe. Use a real apostrophe so the copy
reads correctly in both modal and embedded presentations.
*/}
{t("settings.general.trackingIssuesUseThisTaskAposSTitle", " Tracking issues use this task's title. If a task has no title yet, Fusion can summarize its description using the title summarization model in Project Models. ")}
{!form.autoSummarizeTitles && !form.useAiMergeCommitSummary && !form.githubTrackingEnabledByDefault
? t("settings.general.enableSummarizationInProjectModelsToConfigureThatModel", " Enable summarization in Project Models to configure that model.")
: ""}
{/*
FNXC:GithubImportTracking 2026-07-01-00:00:
This checkbox is project-scoped and import-specific: operators can link imported GitHub issues to GitHub tracking without turning tracking on for every new task.
*/}
setForm((f) => ({ ...f, githubLinkImportedIssuesToTracking: v === true }))}
/>
{/* FNXC:SettingsHelp 2026-07-15-22:40: The row keeps its bespoke `TrackingRepoSelect` widget, but its help still reads like every neighbour's — the affordance belongs to the label line, not to the control, so a custom widget is no reason to fall back to an inline paragraph. */}
{t("settings.general.defaultRepoUsedWhenCreatingGitHubIssuesFor", "Default repo used when creating GitHub issues for tracked tasks. Falls back to the global default if blank.")}
{/* FNXC:SettingsStyling 2026-07-15-17:35: No `help` — this row carried no help copy before the migration, and inventing one would be new operator-facing text rather than a restyle. */}
setForm((f) => ({ ...f, githubAuthMode: v as "gh-cli" | "token" }))}
/>
{(form.githubAuthMode ?? "gh-cli") === "token" && (
setForm((f) => ({ ...f, githubAuthToken: v || undefined }))}
/>
)}