import { diff } from 'deep-diff'; import type { IEvent } from 'interfaces/event'; import { useTheme } from '@mui/system'; import type { JSX, CSSProperties } from 'react'; const DIFF_PREFIXES: Record = { A: ' ', E: ' ', D: '-', N: '+', }; interface IEventDiffResult { key: string; value: JSX.Element; index: number; } interface IEventDiffProps { entry: Partial; sort?: (a: IEventDiffResult, b: IEventDiffResult) => number; } const EventDiff = ({ entry, sort = (a, b) => a.key.localeCompare(b.key), }: IEventDiffProps) => { const theme = useTheme(); const styles: Record = { A: { color: theme.palette.eventLog.edited }, // array edited E: { color: theme.palette.eventLog.edited }, // edited D: { color: theme.palette.eventLog.diffSub }, // deleted N: { color: theme.palette.eventLog.diffAdd }, // added }; const diffs = entry.data && entry.preData ? diff(entry.preData, entry.data) : undefined; const buildItemDiff = (diff: any, key: string) => { let change: JSX.Element | undefined; if (diff.lhs !== undefined) { change = (
- {key}: {JSON.stringify(diff.lhs)}
); } else if (diff.rhs !== undefined) { change = (
+ {key}: {JSON.stringify(diff.rhs)}
); } return change; }; const buildDiff = (diff: any, index: number): IEventDiffResult => { let change: JSX.Element | undefined; const key = diff.path?.join('.') ?? diff.index; if (diff.item) { change = buildItemDiff(diff.item, key); } else if (diff.lhs !== undefined && diff.rhs !== undefined) { change = (
- {key}: {JSON.stringify(diff.lhs)}
+ {key}: {JSON.stringify(diff.rhs)}
); } else { const changeValue = JSON.stringify(diff.rhs || diff.item); change = (
{DIFF_PREFIXES[diff.kind]} {key} {changeValue ? `: ${changeValue}` : diff.kind === 'D' ? ' (deleted)' : ''}
); } return { key: key.toString(), value:
{change}
, index, }; }; let changes: any[] = []; if (diffs) { changes = diffs .map(buildDiff) .sort(sort) .map(({ value }) => value); } else if (entry.data == null || entry.preData == null) { // Just show the data if there is no diff yet. const data = entry.data || entry.preData; changes = [
{JSON.stringify(data, null, 2)}
, ]; } return ( // biome-ignore lint/a11y/noNoninteractiveTabindex:
            {changes.length === 0 ? '(no changes)' : changes}
        
); }; export default EventDiff;