Hone logo
Hone
Problems

React Conflict Resolution System

This challenge involves building a simplified conflict resolution system within a React application. In collaborative environments, multiple users might attempt to edit the same data simultaneously, leading to conflicts. Your task is to create a React component that can detect, display, and allow a user to resolve these data conflicts.

Problem Description

You need to develop a React component that simulates a conflict resolution UI. The component will receive an array of data items, each potentially having a "resolved" status. The core functionality is to identify items that are in a conflicting state (e.g., multiple versions of the same item exist) and present them to the user for manual resolution.

Key Requirements:

  • Data Structure: The system will operate on an array of objects. Each object should have at least an id, value, and a status field. The status can be one of: 'resolved', 'unresolved', or 'conflicted'.
  • Conflict Detection (Simulated): For this challenge, you don't need to implement a complex real-time conflict detection algorithm. Assume that a conflict is indicated by an item having the status set to 'conflicted'.
  • UI for Displaying Conflicts: Render a list of items. Items with status: 'conflicted' should be clearly highlighted and presented in a way that allows for resolution.
  • Resolution Mechanism: For each conflicted item, provide a way for the user to choose a final value. This could be a simple button to select one of the conflicting versions or a text input to manually enter a new value.
  • Updating Status: Upon successful resolution (e.g., clicking a "Resolve" button), the item's status should be updated to 'resolved'.
  • State Management: The component should manage its own internal state for the list of items.

Expected Behavior:

  • When the component receives data with items marked as 'conflicted', these items should be visually distinct (e.g., different background color, a specific icon).
  • For each conflicted item, the UI should present options for resolution.
  • When the user selects a resolution (e.g., choosing one of the conflicting values or entering a new one), and confirms, the item's status should change to 'resolved' and it should no longer appear as a conflict in the UI.
  • Items with status: 'resolved' or 'unresolved' (if they are not part of a conflict) should be displayed normally.

Edge Cases to Consider:

  • What happens if the input array is empty?
  • What if an item has a status other than the expected ones? (For this challenge, assume valid statuses).
  • How to handle multiple conflicting items in the same render.

Examples

Example 1:

Input Data: [
  { id: 1, value: "Document A (v1)", status: "resolved" },
  { id: 2, value: "Document B (v1)", status: "conflicted" },
  { id: 3, value: "Document C", status: "unresolved" }
]

UI Output:
- Document A (v1) [Resolved]
- Document B (v1) [Conflict]
    - Choose Version 1: "Document B (v1)" [Select]
    - Choose Version 2: "Document B (v2)" [Select] (Assume this is another conflicting version not explicitly in input but implied by conflict)
    - Manual Input: [_________] [Resolve]
- Document C [Unresolved]

Explanation: Item 1 is already resolved. Item 3 is unresolved. Item 2 is in conflict, presenting options to resolve it. The example implicitly shows two potential versions for Document B, requiring a selection or manual input.

Example 2:

Input Data: [
  { id: 1, value: "Task 1", status: "resolved" },
  { id: 2, value: "Task 2 (Draft)", status: "conflicted" },
  { id: 3, value: "Task 2 (Final)", status: "conflicted" }
]

UI Output:
- Task 1 [Resolved]
- Task 2 (Draft) [Conflict]
    - Choose Version: "Task 2 (Draft)" [Select]
    - Manual Input: [_________] [Resolve]
- Task 2 (Final) [Conflict]
    - Choose Version: "Task 2 (Final)" [Select]
    - Manual Input: [_________] [Resolve]

Explanation: This example shows two items that are individually flagged as 'conflicted', but the UI should group them logically if they represent the same underlying conflict (e.g., two versions of "Task 2"). For simplicity in this challenge, we'll treat each 'conflicted' item independently as presented in the input. The UI should highlight both "Task 2 (Draft)" and "Task 2 (Final)" as conflicts, offering resolution for each.

Example 3: (After Resolution)

Input Data (Initial): [
  { id: 1, value: "Document A (v1)", status: "resolved" },
  { id: 2, value: "Document B (v1)", status: "conflicted" },
  { id: 3, value: "Document C", status: "unresolved" }
]

User Action: Selects "Document B (v1)" as the resolved value for id: 2.

Output Data (After Resolution): [
  { id: 1, value: "Document A (v1)", status: "resolved" },
  { id: 2, value: "Document B (v1)", status: "resolved" }, // Status updated
  { id: 3, value: "Document C", status: "unresolved" }
]

UI Output:
- Document A (v1) [Resolved]
- Document B (v1) [Resolved] // Now shows as resolved
- Document C [Unresolved]

Explanation: After the user makes a resolution choice for item with id: 2, its status is updated to 'resolved', and the UI reflects this change, no longer presenting it as a conflict.

Constraints

  • The application must be built using React and TypeScript.
  • The component should be a functional component.
  • You can use useState for managing the component's internal data.
  • The number of items in the input array will not exceed 100.
  • The length of any value string will not exceed 255 characters.
  • Performance is not a critical concern for this challenge, but avoid excessively inefficient rendering patterns.

Notes

  • For simplicity, when an item has status: 'conflicted', assume there are at least two versions available for resolution. You can simulate these other versions within your component's rendering logic (e.g., by displaying the original value and a slightly modified version, or just providing a text input).
  • Focus on the UI and the state transitions related to conflict resolution.
  • You can decide on the specific UI elements for presenting conflict options (e.g., radio buttons, dropdowns, simple buttons).
  • Consider how you will pass the initial data into your component (e.g., as a prop).
Loading editor...
typescript