import { diff } from 'deep-diff'; import { type JSX, type CSSProperties, useState, type FC, useId } from 'react'; import { JsonDiffComponent, type JsonValue } from 'json-diff-react'; import { Button, styled, useTheme } from '@mui/material'; import { useUiFlag } from 'hooks/useUiFlag'; const DIFF_PREFIXES: Record = { A: ' ', E: ' ', D: '-', N: '+', }; interface IEventDiffResult { key: string; value: JSX.Element; index: number; } interface IEventDiffProps { entry: { data?: unknown; preData?: unknown }; /** * @deprecated remove with flag improvedJsonDiff */ sort?: (a: IEventDiffResult, b: IEventDiffResult) => number; excludeKeys?: string[]; } const DiffStyles = styled('div')(({ theme }) => ({ color: theme.palette.text.secondary, fontFamily: 'monospace', whiteSpace: 'pre', fontSize: theme.typography.body2.fontSize, '.deletion, .addition': { position: 'relative', '::before': { position: 'absolute', left: 0, top: 0, }, }, '.addition': { color: theme.palette.eventLog.diffAdd, '::before': { content: '"+"', }, }, '.deletion': { color: theme.palette.eventLog.diffSub, '::before': { content: '"-"', }, }, '&[data-change-type="replacement"]': { ':has(.addition)': { color: theme.palette.eventLog.diffAdd, }, ':has(.deletion)': { color: theme.palette.eventLog.diffSub, }, '.addition::before, .deletion::before': { content: 'none', }, }, '.diff:not(:has(*))': { '::before': { content: '"(no changes)"', }, }, })); const ButtonIcon = styled('span')(({ theme }) => ({ marginInlineEnd: theme.spacing(0.5), })); export const NewEventDiff: FC = ({ entry, excludeKeys }) => { const changeType = entry.preData && entry.data ? 'edit' : 'replacement'; const showExpandButton = changeType === 'edit'; const [full, setFull] = useState(false); const diffId = useId(); return ( <> {showExpandButton ? ( ) : null} ); }; const OldEventDiff: FC = ({ 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 (
            {changes.length === 0 ? '(no changes)' : changes}
        
); }; const EventDiff: FC = (props) => { const useNewJsonDiff = useUiFlag('improvedJsonDiff'); if (useNewJsonDiff) { return ; } return ; }; /** * @deprecated remove the default export with flag improvedJsonDiff. Switch imports in files that use this to the named import instead. */ export default EventDiff;