Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,037 changes: 1,037 additions & 0 deletions DiffPlex.Blazor/Components/InteractiveThreeWayMergeViewer.razor

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion DiffPlex.Blazor/Components/Layout/NavMenu.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">DiffPlex.Blazor</a>
</div>
Expand All @@ -25,6 +25,12 @@
<span class="bi bi-file-code-nav-menu" aria-hidden="true"></span> Unified Diff
</NavLink>
</div>

<div class="nav-item px-3">
<NavLink class="nav-link" href="three-way-merge">
<span class="bi bi-diagram-3-nav-menu" aria-hidden="true"></span> Three-Way Merge
</NavLink>
</div>
</nav>
</div>

138 changes: 137 additions & 1 deletion DiffPlex.Blazor/Components/Pages/Examples.razor
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@
@onclick='() => SetViewMode("inline")'>
Inline
</button>
@if (IsThreeWayExample())
{
<button type="button" class="btn @(viewMode == "three-way" ? "btn-secondary" : "btn-outline-secondary")"
@onclick='() => SetViewMode("three-way")'>
Three-Way Merge
</button>
}
</div>
</div>
</div>
Expand All @@ -62,6 +69,16 @@
NewTextHeader="@currentExample.NewHeader"
IgnoreWhiteSpace="true" />
}
else if (viewMode == "three-way")
{
<ThreeWayMergeViewer BaseText="@currentExample.BaseText"
YoursText="@currentExample.YoursText"
TheirsText="@currentExample.TheirsText"
BaseHeader="@currentExample.BaseHeader"
YoursHeader="@currentExample.YoursHeader"
TheirsHeader="@currentExample.TheirsHeader"
IgnoreWhiteSpace="true" />
}
else
{
<InlineDiffViewer OldText="@currentExample.OldText"
Expand All @@ -76,11 +93,117 @@

@code {
private string viewMode = "side-by-side";
private string selectedExample = "code-refactor";
private string selectedExample = "merge-conflict";
private ExampleData? currentExample;

private Dictionary<string, ExampleData> examples = new()
{
["merge-conflict"] = new ExampleData
{
Name = "Merge Conflict",
Description = "Shows a three-way merge scenario with conflicts that need manual resolution.",
BaseHeader = "Common Base",
YoursHeader = "Your Changes",
TheirsHeader = "Their Changes",
BaseText = @"function calculateTotal(items) {
let total = 0;
for (let item of items) {
total += item.price;
}
return total;
}

function processOrder(order) {
// Basic processing
return order;
}",
YoursText = @"function calculateTotal(items, tax = 0.08) {
let total = 0;
for (let item of items) {
total += item.price * item.quantity;
}
return total * (1 + tax);
}

function processOrder(order) {
// Validate order before processing
if (!order.items || order.items.length === 0) {
throw new Error('Order must contain items');
}
return order;
}",
TheirsText = @"function calculateTotal(items, discountRate = 0) {
let total = 0;
for (let item of items) {
total += item.price;
}
return total * (1 - discountRate);
}

function processOrder(order) {
// Add logging
console.log('Processing order:', order.id);
return order;
}"
},
["merge-clean"] = new ExampleData
{
Name = "Clean Merge",
Description = "Shows a three-way merge scenario where changes can be automatically merged without conflicts.",
BaseHeader = "Original Code",
YoursHeader = "Feature Branch",
TheirsHeader = "Main Branch",
BaseText = @"class UserService {
constructor() {
this.users = [];
}

addUser(user) {
this.users.push(user);
}

getUser(id) {
return this.users.find(u => u.id === id);
}
}",
YoursText = @"class UserService {
constructor() {
this.users = [];
this.cache = new Map();
}

addUser(user) {
this.users.push(user);
this.cache.set(user.id, user);
}

getUser(id) {
// Check cache first
if (this.cache.has(id)) {
return this.cache.get(id);
}
return this.users.find(u => u.id === id);
}
}",
TheirsText = @"class UserService {
constructor(database) {
this.users = [];
this.database = database;
}

addUser(user) {
this.users.push(user);
}

getUser(id) {
return this.users.find(u => u.id === id);
}

deleteUser(id) {
this.users = this.users.filter(u => u.id !== id);
}
}"
},
["code-refactor"] = new ExampleData
{
Name = "Code Refactor",
Expand Down Expand Up @@ -284,6 +407,11 @@ var diffModel = differ.BuildDiffModel(oldText, newText);
viewMode = mode;
}

private bool IsThreeWayExample()
{
return currentExample != null && !string.IsNullOrEmpty(currentExample.BaseText);
}

private class ExampleData
{
public string Name { get; set; } = "";
Expand All @@ -292,5 +420,13 @@ var diffModel = differ.BuildDiffModel(oldText, newText);
public string NewHeader { get; set; } = "";
public string OldText { get; set; } = "";
public string NewText { get; set; } = "";

// Three-way merge properties
public string BaseText { get; set; } = "";
public string YoursText { get; set; } = "";
public string TheirsText { get; set; } = "";
public string BaseHeader { get; set; } = "";
public string YoursHeader { get; set; } = "";
public string TheirsHeader { get; set; } = "";
}
}
Loading
Loading