From 362f2fa280fdab210074e9a7e01dde6187924d29 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Sat, 22 Apr 2023 00:49:03 +0200 Subject: feat(new-tool): diff of two json objects --- .../json-diff/diff-viewer/diff-viewer.models.tsx | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/tools/json-diff/diff-viewer/diff-viewer.models.tsx (limited to 'src/tools/json-diff/diff-viewer/diff-viewer.models.tsx') diff --git a/src/tools/json-diff/diff-viewer/diff-viewer.models.tsx b/src/tools/json-diff/diff-viewer/diff-viewer.models.tsx new file mode 100644 index 0000000..5a19feb --- /dev/null +++ b/src/tools/json-diff/diff-viewer/diff-viewer.models.tsx @@ -0,0 +1,119 @@ +import _ from 'lodash'; +import { useCopy } from '@/composable/copy'; +import type { Difference, ArrayDifference, ObjectDifference } from '../json-diff.types'; + +export const DiffRootViewer = ({ diff }: { diff: Difference }) => { + return ( +
+ +
+ ); +}; + +const DiffViewer = ({ diff, showKeys = true }: { diff: Difference; showKeys?: boolean }) => { + const { type, status } = diff; + + if (status === 'updated') { + return ComparisonViewer({ diff, showKeys }); + } + + if (type === 'array') { + return ChildrenViewer({ diff, showKeys, showChildrenKeys: false, openTag: '[', closeTag: ']' }); + } + + if (type === 'object') { + return ChildrenViewer({ diff, showKeys, openTag: '{', closeTag: '}' }); + } + + return LineDiffViewer({ diff, showKeys }); +}; + +const LineDiffViewer = ({ diff, showKeys }: { diff: Difference; showKeys?: boolean }) => { + const { value, key, status, oldValue } = diff; + const valueToDisplay = status === 'removed' ? oldValue : value; + + return ( +
  • + + {showKeys && ( + <> + {key} + {': '} + + )} + {Value({ value: valueToDisplay, status })} + + , +
  • + ); +}; + +const ComparisonViewer = ({ diff, showKeys }: { diff: Difference; showKeys?: boolean }) => { + const { value, key, oldValue } = diff; + + return ( +
  • + {showKeys && ( + <> + {key} + {': '} + + )} + {Value({ value: oldValue, status: 'removed' })} + {Value({ value, status: 'added' })}, +
  • + ); +}; + +const ChildrenViewer = ({ + diff, + openTag, + closeTag, + showKeys, + showChildrenKeys = true, +}: { + diff: ArrayDifference | ObjectDifference; + showKeys: boolean; + showChildrenKeys?: boolean; + openTag: string; + closeTag: string; +}) => { + const { children, key, status, type } = diff; + + return ( +
  • +
    + {showKeys && ( + <> + {key} + {': '} + + )} + + {openTag} + {children.length > 0 &&
      {children.map((diff) => DiffViewer({ diff, showKeys: showChildrenKeys }))}
    } + {closeTag + ','} +
    +
  • + ); +}; + +function formatValue(value: unknown) { + if (_.isNull(value)) { + return 'null'; + } + + return JSON.stringify(value); +} + +const Value = ({ value, status }: { value: unknown; status: string }) => { + const formatedValue = formatValue(value); + + const { copy } = useCopy({ source: formatedValue }); + + return ( + + {formatedValue} + + ); +}; -- cgit v1.2.3