/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/**
* Per-element "what changed" detail (issue #924): geometry move / reshape
* summary + data field deltas. Extracted from ComparePanel.
*/
import { PencilLine } from 'lucide-react';
import { cn } from '@/lib/utils';
import type { ChangeDetail, FieldDelta, GeometrySummary } from '@/lib/compare/describeChange';
import type { CompareRow } from './changeRow';
export function ChangeDetailView({ row, detail }: { row: CompareRow; detail: ChangeDetail }) {
return (
{row.name || row.ifcType}
{row.ifcType.replace(/^Ifc/, '')}
{detail.geometry && (
)}
{detail.data.length > 0 ? (
Data ({detail.data.length})
{detail.data.map((d, i) => )}
) : detail.dataOnlyGeometric ? (
Data fingerprint differs but no field-level change could be pinpointed.
) : !detail.geometry ? (
No field-level detail available.
) : null}
);
}
function GeometryDetail({ summary }: { summary: GeometrySummary }) {
const moved = summary.movedDistance > 0;
const fmt = (n: number) => (Math.abs(n) < 1e-3 ? '0' : n.toFixed(Math.abs(n) >= 1 ? 2 : 3));
const signed = (n: number) => (n > 0 ? `+${fmt(n)}` : fmt(n));
const headline = summary.reshaped ? (moved ? 'Reshaped + moved' : 'Reshaped') : moved ? 'Moved' : 'Geometry changed';
return (
{headline}
{moved && (
{fmt(summary.movedDistance)} m
{' '}(Δx {fmt(summary.delta.x)}, Δy {fmt(summary.delta.y)}, Δz {fmt(summary.delta.z)})
)}
{summary.reshaped && (
size{' '}
(Δx {signed(summary.sizeDelta.x)}, Δy {signed(summary.sizeDelta.y)}, Δz {signed(summary.sizeDelta.z)}) m
)}
{!moved && !summary.reshaped && (
Shape hash differs but the element’s position and size are unchanged.
)}
);
}
function FieldDeltaRow({ delta }: { delta: FieldDelta }) {
const kindColor: Record = {
changed: 'text-[#e0af68]',
added: 'text-[#9ece6a]',
removed: 'text-[#f7768e]',
};
return (
{delta.group && {delta.group}}
{delta.name}
{delta.kind}
{delta.before ?? '—'}
→
{delta.after ?? '—'}
);
}