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
72 changes: 72 additions & 0 deletions src/Web/AdminPanel/Components/ItemDrops/CollapsibleSection.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<div class="card mb-3">
<div class="card-header d-flex align-items-center collapsible-section__header" role="button"
aria-expanded="@this._isExpanded" @onclick="this.Toggle">
<span class="oi @(this._isExpanded ? "oi-chevron-bottom" : "oi-chevron-right") me-2" aria-hidden="true"></span>
<h5 class="mb-0 flex-grow-1">@this.Title</h5>
@if (this.Badge is not null)
{
<span class="badge bg-secondary">@this.Badge</span>
}
</div>
@if (this._isExpanded)
{
<div class="card-body">
@if (!string.IsNullOrWhiteSpace(this.Description))
{
<p class="text-muted small">@this.Description</p>
}
@this.ChildContent
</div>
}
</div>

@code {
private bool _isExpanded;
private bool _initialized;

/// <summary>
/// Gets or sets the title.
/// </summary>
[Parameter]
public string Title { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the description which is shown above the content.
/// </summary>
[Parameter]
public string? Description { get; set; }

/// <summary>
/// Gets or sets the badge text which is shown in the header, e.g. the number of entries.
/// </summary>
[Parameter]
public string? Badge { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the section is expanded initially.
/// </summary>
[Parameter]
public bool InitiallyExpanded { get; set; }

/// <summary>
/// Gets or sets the content.
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }

/// <inheritdoc />
protected override void OnParametersSet()
{
base.OnParametersSet();
if (!this._initialized)
{
this._isExpanded = this.InitiallyExpanded;
this._initialized = true;
}
}

private void Toggle()
{
this._isExpanded = !this._isExpanded;
}
}
90 changes: 90 additions & 0 deletions src/Web/AdminPanel/Components/ItemDrops/CollectionListAdapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// <copyright file="CollectionListAdapter.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Web.AdminPanel.Components.ItemDrops;

using System.Collections;

/// <summary>
/// Adapts a <see cref="ICollection{T}"/> to a <see cref="IList{T}"/>, so that it can be used
/// with components which require a list, e.g. the <see cref="MUnique.OpenMU.Web.Shared.Components.Form.MultiLookupField{TObject}"/>.
/// All modifications are passed through to the underlying collection.
/// </summary>
/// <typeparam name="T">The type of the elements.</typeparam>
public sealed class CollectionListAdapter<T> : IList<T>
{
private readonly ICollection<T> _collection;

/// <summary>
/// Initializes a new instance of the <see cref="CollectionListAdapter{T}"/> class.
/// </summary>
/// <param name="collection">The adapted collection.</param>
public CollectionListAdapter(ICollection<T> collection)
{
this._collection = collection;
}

/// <inheritdoc />
public int Count => this._collection.Count;

/// <inheritdoc />
public bool IsReadOnly => this._collection.IsReadOnly;

/// <inheritdoc />
public T this[int index]
{
get => this._collection.ElementAt(index);
set => throw new NotSupportedException();
}

/// <inheritdoc />
public IEnumerator<T> GetEnumerator() => this._collection.GetEnumerator();

/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

/// <inheritdoc />
public void Add(T item)
{
if (!this._collection.Contains(item))
{
this._collection.Add(item);
}
}

/// <inheritdoc />
public void Clear() => this._collection.Clear();

/// <inheritdoc />
public bool Contains(T item) => this._collection.Contains(item);

/// <inheritdoc />
public void CopyTo(T[] array, int arrayIndex) => this._collection.CopyTo(array, arrayIndex);

/// <inheritdoc />
public bool Remove(T item) => this._collection.Remove(item);

/// <inheritdoc />
public int IndexOf(T item)
{
var index = 0;
foreach (var element in this._collection)
{
if (Equals(element, item))
{
return index;
}

index++;
}

return -1;
}

/// <inheritdoc />
public void Insert(int index, T item) => this.Add(item);

/// <inheritdoc />
public void RemoveAt(int index) => this._collection.Remove(this[index]);
}
102 changes: 102 additions & 0 deletions src/Web/AdminPanel/Components/ItemDrops/DropGroupAssignmentList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// <copyright file="DropGroupAssignmentList.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Web.AdminPanel.Components.ItemDrops;

using System.Collections;
using MUnique.OpenMU.DataModel.Configuration;

/// <summary>
/// A list of owners (e.g. maps or monsters) to which a <see cref="DropItemGroup"/> is assigned.
/// Adding or removing an owner adds or removes the drop item group to or from the
/// drop item groups of the owner.
/// </summary>
/// <typeparam name="TOwner">The type of the owner.</typeparam>
public sealed class DropGroupAssignmentList<TOwner> : IList<TOwner>
where TOwner : class
{
private readonly DropItemGroup _group;
private readonly Func<TOwner, ICollection<DropItemGroup>> _groupsOfOwner;
private readonly List<TOwner> _owners;

/// <summary>
/// Initializes a new instance of the <see cref="DropGroupAssignmentList{TOwner}"/> class.
/// </summary>
/// <param name="group">The drop item group.</param>
/// <param name="allOwners">All possible owners.</param>
/// <param name="groupsOfOwner">The function to get the drop item groups of an owner.</param>
public DropGroupAssignmentList(DropItemGroup group, IEnumerable<TOwner> allOwners, Func<TOwner, ICollection<DropItemGroup>> groupsOfOwner)
{
this._group = group;
this._groupsOfOwner = groupsOfOwner;
this._owners = allOwners.Where(owner => groupsOfOwner(owner).Contains(group)).ToList();
}

/// <inheritdoc />
public int Count => this._owners.Count;

/// <inheritdoc />
public bool IsReadOnly => false;

/// <inheritdoc />
public TOwner this[int index]
{
get => this._owners[index];
set => throw new NotSupportedException();
}

/// <inheritdoc />
public IEnumerator<TOwner> GetEnumerator() => this._owners.GetEnumerator();

/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

/// <inheritdoc />
public void Add(TOwner item)
{
if (this._owners.Contains(item))
{
return;
}

var groups = this._groupsOfOwner(item);
if (!groups.Contains(this._group))
{
groups.Add(this._group);
}

this._owners.Add(item);
}

/// <inheritdoc />
public void Clear()
{
foreach (var owner in this._owners.ToList())
{
this.Remove(owner);
}
}

/// <inheritdoc />
public bool Contains(TOwner item) => this._owners.Contains(item);

/// <inheritdoc />
public void CopyTo(TOwner[] array, int arrayIndex) => this._owners.CopyTo(array, arrayIndex);

/// <inheritdoc />
public bool Remove(TOwner item)
{
this._groupsOfOwner(item).Remove(this._group);
return this._owners.Remove(item);
}

/// <inheritdoc />
public int IndexOf(TOwner item) => this._owners.IndexOf(item);

/// <inheritdoc />
public void Insert(int index, TOwner item) => this.Add(item);

/// <inheritdoc />
public void RemoveAt(int index) => this.Remove(this._owners[index]);
}
Loading
Loading