From f8f0e5a6bf23729b9d3549e44e76a21a9416bfbf Mon Sep 17 00:00:00 2001 From: Jan <41827327+RReventlov@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:53:27 +0200 Subject: [PATCH] [SortableList] Adding Properties FromListId and ToListId (#2385) * feat: allow FluentSortableList to know where an item was dragged from and dropped to * Renamed properties * Changed example back to two lists The swapping is still handled differently (getting the list through the ids) than before. * Reverted to the previous example with added traces for the id. * Added a test to verify the Id is added to the list * Renamed the test to clarify intent * Added unit test for OnUpdate * Changed parameter names to reflect property names * Reverted changes made by the IDE --------- Co-authored-by: Denis Voituron --- ...crosoft.FluentUI.AspNetCore.Components.xml | 12 +++ .../SortableListMoveBetweenLists.razor | 4 + .../SortableList/FluentSortableList.razor | 2 +- .../SortableList/FluentSortableList.razor.cs | 10 +-- .../SortableList/FluentSortableList.razor.js | 4 +- .../FluentSortableListEventArgs.cs | 16 +++- ...SortableList_IdIsAdded.verified.razor.html | 33 ++++++++ .../FluentSortableListTests.razor | 75 +++++++++++++++++-- 8 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 tests/Core/SortableList/FluentSortableListTests.FluentSortableList_IdIsAdded.verified.razor.html diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index 3ca6c314d6..785c9b8e82 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -7959,6 +7959,18 @@ Gets the index of the item in the list after the update. + + + Gets the id of the list the item was in before the update. + May be null if no Id was set for + + + + + Gets the id of the list the item is in after the update. + May be null if no Id was set for + + diff --git a/examples/Demo/Shared/Pages/SortableList/Examples/SortableListMoveBetweenLists.razor b/examples/Demo/Shared/Pages/SortableList/Examples/SortableListMoveBetweenLists.razor index 28fd742f45..86cb6b7577 100644 --- a/examples/Demo/Shared/Pages/SortableList/Examples/SortableListMoveBetweenLists.razor +++ b/examples/Demo/Shared/Pages/SortableList/Examples/SortableListMoveBetweenLists.razor @@ -48,6 +48,8 @@ // remove the item from the old index in list 1 items1.Remove(items1[args.OldIndex]); + + DemoLogger.WriteLine($"Moved item from list {args.FromListId} to list {args.ToListId}"); } private void ListTwoRemove(FluentSortableListEventArgs args) @@ -64,6 +66,8 @@ // remove the item from the old index in list 2 items2.Remove(items2[args.OldIndex]); + + DemoLogger.WriteLine($"Moved item from list {args.FromListId} to list {args.ToListId}"); } private void SortListOne(FluentSortableListEventArgs args) { diff --git a/src/Core/Components/SortableList/FluentSortableList.razor b/src/Core/Components/SortableList/FluentSortableList.razor index b4e58b79b5..ebe0da1162 100644 --- a/src/Core/Components/SortableList/FluentSortableList.razor +++ b/src/Core/Components/SortableList/FluentSortableList.razor @@ -7,7 +7,7 @@ @if (ItemTemplate is not null) { -
+
@foreach (var item in Items) {
@ItemTemplate(item)
diff --git a/src/Core/Components/SortableList/FluentSortableList.razor.cs b/src/Core/Components/SortableList/FluentSortableList.razor.cs index 70b3a29911..09b4f3a59a 100644 --- a/src/Core/Components/SortableList/FluentSortableList.razor.cs +++ b/src/Core/Components/SortableList/FluentSortableList.razor.cs @@ -126,22 +126,22 @@ protected bool GetItemFiltered(TItem item) } [JSInvokable] - public void OnUpdateJS(int oldIndex, int newIndex) + public void OnUpdateJS(int oldIndex, int newIndex, string fromListId, string toListId) { if (OnUpdate.HasDelegate) { - // invoke the OnUpdate event passing in the oldIndex and the newIndex - OnUpdate.InvokeAsync(new FluentSortableListEventArgs(oldIndex, newIndex)); + // invoke the OnUpdate event passing in the oldIndex, the newIndex, the fromId and the toId + OnUpdate.InvokeAsync(new FluentSortableListEventArgs(oldIndex, newIndex, fromListId, toListId)); } } [JSInvokable] - public void OnRemoveJS(int oldIndex, int newIndex) + public void OnRemoveJS(int oldIndex, int newIndex, string fromListId, string toListId) { if (OnRemove.HasDelegate) { // remove the item from the list - OnRemove.InvokeAsync(new FluentSortableListEventArgs(oldIndex, newIndex)); + OnRemove.InvokeAsync(new FluentSortableListEventArgs(oldIndex, newIndex, fromListId, toListId)); } } diff --git a/src/Core/Components/SortableList/FluentSortableList.razor.js b/src/Core/Components/SortableList/FluentSortableList.razor.js index 857b417112..324b5e4e0d 100644 --- a/src/Core/Components/SortableList/FluentSortableList.razor.js +++ b/src/Core/Components/SortableList/FluentSortableList.razor.js @@ -16,7 +16,7 @@ export function init(list, group, pull, put, sort, handle, filter, fallback, com event.to.insertBefore(event.item, event.to.childNodes[event.oldIndex]); // Notify .NET to update its model and re-render - component.invokeMethodAsync('OnUpdateJS', event.oldDraggableIndex, event.newDraggableIndex); + component.invokeMethodAsync('OnUpdateJS', event.oldDraggableIndex, event.newDraggableIndex, event.from.id, event.to.id); }, onRemove: (event) => { if (event.pullMode === 'clone') { @@ -28,7 +28,7 @@ export function init(list, group, pull, put, sort, handle, filter, fallback, com event.from.insertBefore(event.item, event.from.childNodes[event.oldIndex]); // Notify .NET to update its model and re-render - component.invokeMethodAsync('OnRemoveJS', event.oldDraggableIndex, event.newDraggableIndex); + component.invokeMethodAsync('OnRemoveJS', event.oldDraggableIndex, event.newDraggableIndex, event.from.id, event.to.id); } }); } diff --git a/src/Core/Components/SortableList/FluentSortableListEventArgs.cs b/src/Core/Components/SortableList/FluentSortableListEventArgs.cs index 07475fbcae..483ed3e23f 100644 --- a/src/Core/Components/SortableList/FluentSortableListEventArgs.cs +++ b/src/Core/Components/SortableList/FluentSortableListEventArgs.cs @@ -7,10 +7,12 @@ public FluentSortableListEventArgs() } - public FluentSortableListEventArgs(int oldIndex, int newIndex) + public FluentSortableListEventArgs(int oldIndex, int newIndex, string? fromListId, string? toListId) { OldIndex = oldIndex; NewIndex = newIndex; + FromListId = fromListId; + ToListId = toListId; } /// @@ -22,4 +24,16 @@ public FluentSortableListEventArgs(int oldIndex, int newIndex) /// Gets the index of the item in the list after the update. /// public int NewIndex { get; } + + /// + /// Gets the id of the list the item was in before the update. + /// May be null if no Id was set for + /// + public string? FromListId { get; } + + /// + /// Gets the id of the list the item is in after the update. + /// May be null if no Id was set for + /// + public string? ToListId { get; } } diff --git a/tests/Core/SortableList/FluentSortableListTests.FluentSortableList_IdIsAdded.verified.razor.html b/tests/Core/SortableList/FluentSortableListTests.FluentSortableList_IdIsAdded.verified.razor.html new file mode 100644 index 0000000000..6f95a3347d --- /dev/null +++ b/tests/Core/SortableList/FluentSortableListTests.FluentSortableList_IdIsAdded.verified.razor.html @@ -0,0 +1,33 @@ + +
+
+
Item 1
+
+
+
Item 2
+
+
+
Item 3
+
+
+
Item 4
+
+
+
Item 5
+
+
+
Item 6
+
+
+
Item 7
+
+
+
Item 8
+
+
+
Item 9
+
+
+
Item 10
+
+
diff --git a/tests/Core/SortableList/FluentSortableListTests.razor b/tests/Core/SortableList/FluentSortableListTests.razor index 17686c32ea..14c623a166 100644 --- a/tests/Core/SortableList/FluentSortableListTests.razor +++ b/tests/Core/SortableList/FluentSortableListTests.razor @@ -1,5 +1,6 @@ @using Xunit; @inherits TestContext + @code { public class Item @@ -23,17 +24,81 @@ public void FluentSortableList_Default() { // Arrange && Act - + var cut = Render(@ - -
@context.Name
-
-
); + +
@context.Name
+
+ ); // Assert cut.Verify(); } + [Fact] + public void FluentSortableList_IdIsAdded() + { + // Arrange && Act + + var cut = Render(@ + +
@context.Name
+
+
); + // Assert + cut.Verify(); + } + + [Fact] + public void FluentSortableList_OnUpdate() + { + // Arrange + FluentSortableListEventArgs? args = null; + var callback = new EventCallbackFactory().Create + (this, (e => args = e)); + var sortableList = new FluentSortableList() + { + Items = items, + OnUpdate = callback + }; + + // Act + sortableList.OnUpdateJS(0, 1, "fromList", "toList"); + + // Verify + Assert.Equal(new FluentSortableListEventArgs(0, 1, "fromList", "toList"), args, + FluentSortableListEventArgsComparer); + } + + private static bool FluentSortableListEventArgsComparer(FluentSortableListEventArgs? first, FluentSortableListEventArgs? second) + { + if (first is null || second is null) + { + return false; + } + + if (first.FromListId is null || !first.FromListId.Equals(second.FromListId)) + { + return false; + } + + if (first.ToListId is null || !first.ToListId.Equals(second.ToListId)) + { + return false; + } + + if (first.OldIndex != second.OldIndex) + { + return false; + } + + if (first.NewIndex != second.NewIndex) + { + return false; + } + + return true; + } }