Assessor_2.0/src/features/finding-reader/PolicyProblemSummary.tsx

45 lines
3.2 KiB
TypeScript

import type { PolicyProblemSummary as Summary } from '../../profiles/group-policy/problem-summary';
import { policyBaselinePackageLabel } from '../../profiles/group-policy/baseline-comparison-summary';
import { PathText } from '../../components/PathText/PathText';
import { highlightText } from '../../components/HighlightText/highlight-text';
/** First-read block: configured versus expected, who sets it, what the flags mean and the next step. */
export function PolicyProblemSummary({ summary, outcome, search }: { summary: Summary; outcome: string; search: string }) {
return <>
<section className="policy-problem" aria-label={summary.heading} data-outcome={outcome}>
<h4>{summary.heading}</h4>
<dl className="policy-problem__values">
{summary.configured.length > 0 && <div><dt>Configured</dt>
<dd>{summary.configured.map((entry, index) => {
// Red: differs from every variant. Green: matches every variant. Neutral: depends on the template.
const content = <><PathText value={entry.text} search={search}/></>;
return <span className="policy-problem__entry" data-state={entry.state ?? 'neutral'} key={index}>
{entry.state ? <span className={`policy-value-mark is-${entry.state}`}>{content}</span> : content}
{entry.note && <span className="policy-problem__note"> · {entry.note}</span>}
</span>;
})}</dd></div>}
{summary.expected.length > 0 && <div><dt>Expected</dt>
<dd>{summary.expected.map((item, index) => <span className="policy-problem__entry" key={index}><PathText value={item} search={search}/></span>)}</dd></div>}
{summary.additional.length > 0 && <div><dt>Additional entries</dt>
<dd>{summary.additional.map((item, index) => <span className="policy-problem__entry" key={index}><PathText value={item} search={search}/></span>)}</dd></div>}
{summary.missing.length > 0 && <div><dt>Missing entries</dt>
<dd>{summary.missing.map((item, index) => <span className="policy-problem__entry" key={index}><PathText value={item} search={search}/></span>)}</dd></div>}
</dl>
{summary.context.map((line, index) => <p className="policy-problem__context" key={index}>{highlightText(line, search)}</p>)}
{summary.flags.map((line, index) => <p className="policy-problem__flag" key={index}>{highlightText(line, search)}</p>)}
</section>
{/* The next step is its own block so its marker stays distinct from the problem outcome. */}
{(summary.nextSteps.length > 0 || summary.nextStepIntro) && <section className="policy-next-step" aria-label="Next step">
<h4>Next step</h4>
{summary.nextStepIntro && <p>{summary.nextStepIntro}</p>}
{summary.nextSteps.map((group, index) => <div className="policy-problem__step" key={index}>
<p className="policy-guidance-text"><PathText value={group.text} search={search} label="Remediation"/></p>
{summary.nextStepPackages && <p className="policy-problem__packages">{highlightText(policyBaselinePackageLabel(group.packages, index === 0 && summary.nextSteps.length > 1), search)}</p>}
</div>)}
{summary.affectedSources.length > 0 && <p className="policy-problem__sources">
In: {highlightText(summary.affectedSources.join(', '), search)}
</p>}
</section>}
</>;
}