Skip to content

Commit adbf0cb

Browse files
authored
Merge pull request CactuseSecurity#3147 from SolidProgramming/issue_3145
Merge: Fixed odering in edit approle
2 parents 23abb96 + 4339999 commit adbf0cb

File tree

11 files changed

+139
-17
lines changed

11 files changed

+139
-17
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using FWO.Services.EventMediator.Interfaces;
2+
3+
namespace FWO.Services.EventMediator;
4+
5+
public class EventMediator : IEventMediator
6+
{
7+
private readonly Dictionary<Type, Dictionary<string, List<Action<IEvent>>>> _handlers = [];
8+
9+
/// <summary>
10+
/// Adds the handler as an invokeable action.
11+
/// </summary>
12+
/// <typeparam name="TEvent"></typeparam>
13+
/// <param name="name"></param>
14+
/// <param name="handler"></param>
15+
public void Subscribe<TEvent>(string name, Action<TEvent> handler) where TEvent : class, IEvent
16+
{
17+
if(!_handlers.ContainsKey(typeof(TEvent)))
18+
{
19+
_handlers[typeof(TEvent)] = [];
20+
}
21+
22+
if(!_handlers[typeof(TEvent)].TryGetValue(name, out List<Action<IEvent>>? value))
23+
{
24+
value = [];
25+
_handlers[typeof(TEvent)][name] = value;
26+
}
27+
28+
value.Add(e => handler((TEvent)e));
29+
}
30+
31+
/// <summary>
32+
/// If matching subscription handler was found it will be invoked.
33+
/// </summary>
34+
/// <typeparam name="TEvent"></typeparam>
35+
/// <param name="name"></param>
36+
/// <param name="event"></param>
37+
public void Publish<TEvent>(string name, TEvent @event) where TEvent : class, IEvent
38+
{
39+
if(_handlers.TryGetValue(typeof(TEvent), out Dictionary<string, List<Action<IEvent>>>? actions)
40+
&& actions.TryGetValue(name, out List<Action<IEvent>>? handlers))
41+
{
42+
foreach(Action<IEvent> handler in handlers)
43+
{
44+
handler(@event);
45+
}
46+
}
47+
}
48+
49+
/// <summary>
50+
/// Unsubscribe of ALL events of the given type matching the name.
51+
/// </summary>
52+
/// <typeparam name="TEvent"></typeparam>
53+
/// <param name="event"></param>
54+
/// <returns>True/False if remove was successfull</returns>
55+
public bool Unsubscribe<TEvent>(string name) where TEvent : class, IEvent
56+
{
57+
if(_handlers.ContainsKey(typeof(TEvent)) && _handlers[typeof(TEvent)].ContainsKey(name))
58+
{
59+
return _handlers[typeof(TEvent)].Remove(name);
60+
}
61+
62+
return false;
63+
}
64+
}
65+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using FWO.Services.EventMediator.Interfaces;
2+
3+
namespace FWO.Services.EventMediator.Events
4+
{
5+
public class CollectionChangedEvent(CollectionChangedEventArgs? eventArgs = default) : IEvent
6+
{
7+
public IEventArgs? EventArgs { get; set; } = eventArgs;
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using FWO.Services.EventMediator.Interfaces;
2+
3+
namespace FWO.Services.EventMediator.Events
4+
{
5+
public class CollectionChangedEventArgs(IEnumerable<dynamic> collection) : IEventArgs
6+
{
7+
IEnumerable<dynamic> Collection { get; } = collection;
8+
}
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace FWO.Services.EventMediator.Interfaces
2+
{
3+
public interface IEvent
4+
{
5+
public IEventArgs? EventArgs { get; set; }
6+
}
7+
}
8+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace FWO.Services.EventMediator.Interfaces
2+
{
3+
public interface IEventArgs { }
4+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace FWO.Services.EventMediator.Interfaces
2+
{
3+
public interface IEventMediator
4+
{
5+
void Subscribe<TEvent>(string name, Action<TEvent> handler) where TEvent : class, IEvent;
6+
void Publish<TEvent>(string name, TEvent @event) where TEvent : class, IEvent;
7+
bool Unsubscribe<TEvent>(string name) where TEvent : class, IEvent;
8+
}
9+
}

roles/lib/files/FWO.Services/ModellingAppRoleHandler.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using FWO.Api.Client;
1+
using FWO.Api.Client;
22
using FWO.Api.Client.Queries;
33
using FWO.Data;
44
using FWO.Data.Modelling;
@@ -21,7 +21,6 @@ public class ModellingAppRoleHandler : ModellingHandlerBase
2121

2222
private ModellingManagedIdString OrigId = new();
2323

24-
2524
public ModellingAppRoleHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application,
2625
List<ModellingAppRole> appRoles, ModellingAppRole appRole, List<ModellingAppServer> availableAppServers,
2726
List<KeyValuePair<int, long>> availableNwElems, bool addMode, Action<Exception?, string, string, bool> displayMessageInUi, bool isOwner = true, bool readOnly = false)

roles/ui/files/FWO.UI/Pages/NetworkModelling/EditAppRole.razor

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
@using FWO.Services.EventMediator.Events
2+
@using FWO.Services.EventMediator.Interfaces
13
@using FWO.Ui.Display
24

35
@inject ApiConnection apiConnection
46
@inject UserConfig userConfig
7+
@inject IEventMediator EventMediator
58

69
@if (AppRoleHandler != null && Display)
710
{
811
<PopUp Title="@(AppRoleHandler.ReadOnly ? "" : (AppRoleHandler.AddMode ? userConfig.GetText("add_app_role") : userConfig.GetText("edit_app_role")))"
9-
Size="@(AppRoleHandler.ReadOnly ? PopupSize.Medium : PopupSize.Large)" Show="@Display" OnClose="Close">
12+
Size="@(AppRoleHandler.ReadOnly ? PopupSize.Medium : PopupSize.Large)" Show="@Display" OnClose="Close">
1013
<Body>
1114
<div class="row mt-2">
1215
@if (!AppRoleHandler.ReadOnly)
@@ -26,7 +29,7 @@
2629
{
2730
<div class="col-sm-8">
2831
<Dropdown ElementType="ModellingNetworkArea" SelectedElement="AppRoleHandler.ActAppRole.Area" ElementToString="@(a => a.Display() + DisplayObjectCount(a))"
29-
SelectedElementChanged="OnSelectedAreaChanged" Elements="areas" Nullable="true">
32+
SelectedElementChanged="OnSelectedAreaChanged" Elements="areas" Nullable="true">
3033
<ElementTemplate Context="area">
3134
@((MarkupString)DisplayAreaWithObjectCount(area))
3235
</ElementTemplate>
@@ -90,11 +93,11 @@
9093
}
9194
else
9295
{
93-
<OrderByDropdown CssClass="bg-secondary" @ref="orderByDropdown" TCollectionItem="ModellingAppServer" Collection="AppRoleHandler.AppServerToAdd" CollectionReordered="OnCollectionReordered" ElementProperties="orderByDropdownProperties" />
96+
<OrderByDropdown CssClass="bg-secondary" @ref="orderByDropdown" TCollectionItem="ModellingAppServer" Collection="ModellingAppServerWrapper.Resolve(AppRoleHandler.ActAppRole.AppServers).Concat(AppRoleHandler.AppServerToAdd).ToList()" CollectionReordered="OnCollectionReordered" ElementProperties="orderByDropdownProperties" />
9497
<div class="dropzone-scrollable dropzone bg-secondary"
95-
ondragover="event.preventDefault();"
96-
ondragstart="event.dataTransfer.setData('', event.target.id);"
97-
@ondrop="HandleServerDrop">
98+
ondragover="event.preventDefault();"
99+
ondragstart="event.dataTransfer.setData('', event.target.id);"
100+
@ondrop="HandleServerDrop">
98101
<EditList ElementType="ModellingAppServer" Elements="ModellingAppServerWrapper.Resolve(AppRoleHandler.ActAppRole.AppServers)" ElementsToAdd="AppRoleHandler.AppServerToAdd" ElementsToDelete="AppRoleHandler.AppServerToDelete" StdLayout="false" ElementsRemoved="OnAppServerRemovedFromEditList">
99102
<Display>
100103
<div class="row">
@@ -136,7 +139,7 @@
136139
</PopUp>
137140
<InProgress Display="workInProgress" />
138141
<Confirm @bind-Display="ShowAreaChangeConfirmation" AllowedRoles="@Roles.Modeller" RenderMessageAsHtml="true"
139-
Message="@(userConfig.GetText("nwareachange_clear_app_servers"))" PerformAction="AreaChangeConfirmation" Title="@(userConfig.GetText("confirm"))" />
142+
Message="@(userConfig.GetText("nwareachange_clear_app_servers"))" PerformAction="AreaChangeConfirmation" Title="@(userConfig.GetText("confirm"))" />
140143
}
141144
@code
142145
{
@@ -161,6 +164,7 @@
161164
[Parameter]
162165
public Func<Task> RefreshParent { get; set; } = DefaultInit.DoNothing;
163166

167+
private readonly static CollectionChangedEvent OnCollectionChanged = new();
164168

165169
private ModellingDnDContainer Container { get; set; } = new();
166170
int sidebarLeftWidth = GlobalConst.kObjLibraryWidth;
@@ -291,6 +295,9 @@
291295

292296
workInProgress = true;
293297
await AppRoleHandler.InitAppRole(newArea);
298+
299+
EventMediator.Publish<CollectionChangedEvent>(nameof(EditAppRole), OnCollectionChanged);
300+
294301
workInProgress = false;
295302
}
296303
}

roles/ui/files/FWO.UI/Pages/NetworkModelling/ManualAppServer.razor

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@using FWO.Ui.Display
1+
@using FWO.Ui.Display
22
@using System.Text.Json
33

44
@attribute [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")]
@@ -109,7 +109,6 @@
109109
private bool workInProgress = false;
110110
private bool firstTry = true;
111111

112-
113112
protected override void OnInitialized()
114113
{
115114
try

roles/ui/files/FWO.UI/Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
using Microsoft.AspNetCore.Components.Authorization;
1010
using Microsoft.AspNetCore.Components.Server.Circuits;
1111
using RestSharp;
12-
using System.Diagnostics;
13-
using PuppeteerSharp;
12+
using FWO.Services.EventMediator.Interfaces;
13+
using FWO.Services.EventMediator;
1414

1515

1616
// Implicitly call static constructor so background lock process is started
@@ -38,6 +38,7 @@
3838
builder.Services.AddScoped<AuthenticationStateProvider, AuthStateProvider>();
3939
builder.Services.AddScoped<CircuitHandler, CircuitHandlerService>();
4040
builder.Services.AddScoped<KeyboardInputService, KeyboardInputService>();
41+
builder.Services.AddScoped<IEventMediator, EventMediator>();
4142

4243
string ApiUri = ConfigFile.ApiServerUri;
4344
string MiddlewareUri = ConfigFile.MiddlewareServerUri;

0 commit comments

Comments
 (0)