React Conflict Resolution Component
This challenge asks you to build a reusable React component that handles and visually presents conflicting data updates from different sources. Imagine a collaborative editing scenario where multiple users are simultaneously modifying the same data – this component will help manage and resolve those conflicts gracefully, providing a clear interface for the user to choose the correct version. This is a common requirement in collaborative applications and data synchronization systems.
Problem Description
You need to create a ConflictResolver component in React using TypeScript. This component will receive two data objects, versionA and versionB, representing potentially conflicting versions of the same data. It should also receive a resolve callback function, which will be called with the chosen version (either versionA or versionB) when the user resolves the conflict. The component should display both versions side-by-side, highlighting the differences, and provide buttons for the user to select either version.
Key Requirements:
- Data Display: Clearly display both
versionAandversionBin a readable format. For simplicity, assume the data is a simple JavaScript object with string values. - Difference Highlighting: Visually highlight the differences between the two versions. A simple approach is to use different background colors for keys that have different values.
- Resolution Buttons: Provide buttons labeled "Choose Version A" and "Choose Version B" that, when clicked, call the
resolvecallback with the corresponding version. - Loading State: Include a loading state. The component should display a "Loading..." message while
versionAandversionBare being fetched or processed. - Error Handling: If either
versionAorversionBisnullorundefined, display an appropriate error message ("Version A missing" or "Version B missing").
Expected Behavior:
- Initially, the component should display a "Loading..." message.
- Once
versionAandversionBare provided, the component should render both versions side-by-side, highlighting differences. - Clicking "Choose Version A" should call the
resolvecallback withversionA. - Clicking "Choose Version B" should call the
resolvecallback withversionB. - If either version is missing, an error message should be displayed instead of the versions.
Edge Cases to Consider:
- What happens if both versions are identical? (Should still display them, no highlighting needed).
- What happens if one version is missing but the other is present? (Display the present version and an error message for the missing one).
- What if the objects have different keys? (Highlight all keys as different).
- Handle potential null or undefined values within the objects themselves.
Examples
Example 1:
Input:
versionA: { name: "Alice", age: "30", city: "New York" }
versionB: { name: "Alice", age: "31", city: "London" }
resolve: (version) => console.log("Resolved with:", version)
Output:
[Component displaying versionA and versionB side-by-side, with the 'age' key highlighted differently in each version. Buttons "Choose Version A" and "Choose Version B" are present.]
Explanation: The 'age' key has different values in the two versions, so it's highlighted. Clicking either button will call the resolve function with the corresponding version.
Example 2:
Input:
versionA: null
versionB: { name: "Bob", age: "25", city: "Paris" }
resolve: (version) => console.log("Resolved with:", version)
Output:
[Component displaying an error message: "Version A missing" and versionB side-by-side.]
Explanation: Version A is null, so the component displays an error message instead of attempting to render it.
Example 3:
Input:
versionA: { name: "Charlie", age: "40", city: "Berlin" }
versionB: { name: "Charlie", age: "40", city: "Berlin" }
resolve: (version) => console.log("Resolved with:", version)
Output:
[Component displaying versionA and versionB side-by-side. No highlighting is present.]
Explanation: Both versions are identical, so no highlighting is needed.
Constraints
- The component should be reusable and accept
versionA,versionB, andresolveas props. - The data objects are assumed to be simple JavaScript objects with string values. No nested objects or arrays are expected.
- The visual highlighting should be clear and easy to understand.
- The component should be performant enough to handle objects with up to 20 key-value pairs.
- The
resolvecallback should be called with eitherversionAorversionB(not a merged version).
Notes
- Consider using CSS classes to style the component and highlight differences.
- You can use a library like
lodashfor comparing objects if you find it helpful, but it's not required. - Focus on creating a clear and functional component that meets the requirements. Advanced features like diff algorithms are not necessary for this challenge.
- Think about how to handle loading states and error conditions gracefully.
- Type safety is important – leverage TypeScript to ensure the props are correctly typed.