← Files Codex Security CloudARCHIVED FILE
.internal/defense-factory-ui/src/workbench/scan-setup-layout.tsx
6.44 KB · Oct 5, 2026 · 18:24 UTC
import { Info as InfoIcon } from "@oai/ds/icons/info";
import { SegmentedControl } from "@oai/ds/ui/segmented-control";
import { Tooltip } from "@oai/ds/ui/tooltip";
import type { ReactNode } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { WorkbenchButton as Button } from "./controls";
import { WorkbenchPageHeader, WorkbenchState } from "./layout";
import { scanTypeDescriptions, scanTypeLabels } from "./scan-types";
import { workbenchStyles } from "./styles";
export function ScanSetupPage({ children }: { children: ReactNode }) {
const intl = useIntl();
return (
<div
className={[workbenchStyles.detailPage, "mx-auto max-w-4xl"].join(" ")}
>
<WorkbenchPageHeader
kind="detail"
title={intl.formatMessage({
id: "codexSecurity.workbench.scans.launch.title",
defaultMessage: "New Scan",
description:
"Main page heading on the dedicated one-time repository security scan setup page.",
})}
/>
{children}
</div>
);
}
export function ScanSetupForm({
children,
footer,
}: {
children: ReactNode;
footer?: ReactNode;
}) {
return (
<div className="flex min-h-0 flex-col gap-4">
<div className={[workbenchStyles.card, "overflow-hidden"].join(" ")}>
<div className="px-3 py-2">{children}</div>
</div>
{footer ? (
<footer className="flex flex-wrap justify-end gap-2">{footer}</footer>
) : null}
</div>
);
}
export function ScanSetupFieldRow({
label,
value,
}: {
label: ReactNode;
value: ReactNode;
}) {
return (
<div className="flex min-w-0 flex-col gap-2 py-3 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<div className="text-token-text-tertiary flex min-w-0 items-center gap-2 text-[14px] leading-5">
{label}
</div>
<div className="text-token-text-primary min-w-0 text-[14px] leading-5 sm:max-w-[70%] sm:text-end">
{value}
</div>
</div>
);
}
export type ScanSetupScope = "diff" | "full-commit";
export function ScanSetupScopeFields({
scope,
disabled,
onScopeChange,
}: {
scope: ScanSetupScope;
disabled: boolean;
onScopeChange: (scope: ScanSetupScope) => void;
}) {
const intl = useIntl();
const scopeLabel = intl.formatMessage({
id: "codexSecurity.workbench.scans.launch.scope.label",
defaultMessage: "What to scan",
description:
"Short field label on the Security New Scan page describing what a scan analyzes.",
});
const options = {
diff: {
label: intl.formatMessage(scanTypeLabels.commit_scan),
description: intl.formatMessage(scanTypeDescriptions.commit_scan),
timing: intl.formatMessage({
id: "codexSecurity.workbench.scans.launch.timing.new_commits",
defaultMessage: "As new commits arrive",
description:
"Read-only timing value when Commit changes is selected. Creating this configuration monitors new commits.",
}),
},
"full-commit": {
label: intl.formatMessage(scanTypeLabels.repository_scan),
description: intl.formatMessage(scanTypeDescriptions.repository_scan),
timing: intl.formatMessage({
id: "codexSecurity.workbench.scans.launch.timing.once",
defaultMessage: "Run once now",
description: "Read-only timing value for a one-time repository scan.",
}),
},
} satisfies Record<
ScanSetupScope,
{ label: string; description: string; timing: string }
>;
return (
<>
<ScanSetupFieldRow
label={
<Tooltip
content={
<div className="space-y-2">
{(Object.keys(options) as ScanSetupScope[]).map((value) => (
<p key={value}>
<span className="block font-medium">
{options[value].label}
</span>
{options[value].description}
</p>
))}
</div>
}
align="start"
>
<button
type="button"
aria-label={intl.formatMessage({
id: "codexSecurity.workbench.scans.launch.scope.info",
defaultMessage: "About scan options",
description:
"Accessible label for help comparing commit-change and repository scans.",
})}
className="interactive-button inline-flex items-center gap-1.5 rounded-sm"
>
{scopeLabel}
<InfoIcon className="icon-sm" aria-hidden />
</button>
</Tooltip>
}
value={
<div className="puik-root w-fit">
<SegmentedControl<ScanSetupScope>
className="df-segmented-control"
value={scope}
onChange={onScopeChange}
aria-label={scopeLabel}
disabled={disabled}
>
<SegmentedControl.Option value="diff">
{options.diff.label}
</SegmentedControl.Option>
<SegmentedControl.Option value="full-commit">
{options["full-commit"].label}
</SegmentedControl.Option>
</SegmentedControl>
</div>
}
/>
<ScanSetupFieldRow
label={
<FormattedMessage
id="codexSecurity.workbench.scans.launch.timing.label"
defaultMessage="When to scan"
description="Short label for the read-only timing row on the Security New Scan page."
/>
}
value={<span>{options[scope].timing}</span>}
/>
</>
);
}
export function ScanSetupNotice({
children,
action,
loading = false,
}: {
children?: ReactNode;
action?: ReactNode;
loading?: boolean;
}) {
return (
<div className="my-2">
<WorkbenchState variant="inline" action={action} loading={loading}>
{children}
</WorkbenchState>
</div>
);
}
export function ScanSetupRetryNotice({
children,
onRetry,
retrying = false,
}: {
children: ReactNode;
onRetry: () => void;
retrying?: boolean;
}) {
return (
<ScanSetupNotice
action={
<Button color="outlineSurface" loading={retrying} onClick={onRetry}>
<FormattedMessage
id="codexSecurity.workbench.scans.launch.retry"
defaultMessage="Retry"
description="Short recovery action on the Security New Scan form."
/>
</Button>
}
>
{children}
</ScanSetupNotice>
);
}
SHA-256: 7b5a91fa8258385bfeb5ae0789bdcdd268ddd005f0ec409c96b8924c6be7845b