Resolve "Plugin support" #68

Merged
leon.hoppe merged 4 commits from feature/plugins into dev 2025-02-05 17:57:00 +01:00
5 changed files with 73 additions and 61 deletions
Showing only changes of commit fb761c74d2 - Show all commits

View File

@@ -12,33 +12,12 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="0648788e-7696-4e60-bf12-5d5601f33d8c" name="Changes" comment=""> <list default="true" id="0648788e-7696-4e60-bf12-5d5601f33d8c" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Annotations/EventHandlerAttribute.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Annotations/PluginConfiguratorAttribute.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/EntryEvent.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/HopFrameEventArgs.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/PageChangeEvent.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/PluginEventContainer.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/ReloadEvent.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/SearchEvent.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Events/ValidationEvent.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/HopFramePlugin.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/testing/HopFrame.Testing/TestPlugin.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Config/DbContextConfig.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Config/DbContextConfig.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Config/HopFrameConfig.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Config/HopFrameConfig.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Config/TableConfig.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Config/TableConfig.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Events/EventTypes.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Callbacks/CallbackTypes.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Events/HopEventHandler.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Callbacks/HopCallbackHandler.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Events/IEventEmitter.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Callbacks/ICallbackEmitter.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/ServiceCollectionExtensions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/ServiceCollectionExtensions.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/Services/Implementations/EventEmitter.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/Services/Implementations/CallbackEmitter.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Web/HopFrameConfiguratorExtensions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/HopFrameConfiguratorExtensions.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Web/ServiceCollectionExtensions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/ServiceCollectionExtensions.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/testing/HopFrame.Testing/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/testing/HopFrame.Testing/Program.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/testing/HopFrame.Testing/TestPlugin.cs" beforeDir="false" afterPath="$PROJECT_DIR$/testing/HopFrame.Testing/TestPlugin.cs" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -82,6 +61,7 @@
<component name="HighlightingSettingsPerFile"> <component name="HighlightingSettingsPerFile">
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/02/6ae7626a/IList.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/02/6ae7626a/IList.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/5b/a350be00/IEnumerable.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/5b/a350be00/IEnumerable.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/62/1fb63ed0/IDisposable.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/8b/db8582a3/IList`1.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/8b/db8582a3/IList`1.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/ad/ba9a50e7/ICollection.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/ad/ba9a50e7/ICollection.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/fc/6f7933d2/ICollection`1.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/c73b3c6c598640c592fd3c6fa226c286e90908/fc/6f7933d2/ICollection`1.cs" root0="FORCE_HIGHLIGHTING" />
@@ -93,6 +73,7 @@
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/439c4ee753b23e743cc14119593bc889751f9eb0b38997577d8e4c47c4fed/ToCollection.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/439c4ee753b23e743cc14119593bc889751f9eb0b38997577d8e4c47c4fed/ToCollection.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/4c41a7d338749915157d56585365d1693fbad6be8231d3d583b1cf10d16896d9/FluentIcon.razor.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/4c41a7d338749915157d56585365d1693fbad6be8231d3d583b1cf10d16896d9/FluentIcon.razor.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/4ee221fd7e91e9a4c14ff82aae2ee938edecde35a934133e991aba56aa9499/Icon.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/4ee221fd7e91e9a4c14ff82aae2ee938edecde35a934133e991aba56aa9499/Icon.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/558c1d46e1e21d2e78ee2ab67a674f6927bf95355b2f245f35d74bb5ec0f92/CancellationTokenSource.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/5a69b82eed595b731b82667db08722b69b82482e275cf32dfb219190e3dc49/CollectionEntry.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/5a69b82eed595b731b82667db08722b69b82482e275cf32dfb219190e3dc49/CollectionEntry.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/60e7b22380df80ef6fefe43138047f49ec6eff4b25c12b42ce3d6ed5aac/MethodInvokerCommon.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/60e7b22380df80ef6fefe43138047f49ec6eff4b25c12b42ce3d6ed5aac/MethodInvokerCommon.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/642391624bd5c30b3411a11434588aba4906207335166b784bf3a4325f6c7/NavigationEntry.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/642391624bd5c30b3411a11434588aba4906207335166b784bf3a4325f6c7/NavigationEntry.cs" root0="FORCE_HIGHLIGHTING" />
@@ -134,28 +115,28 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
".NET Launch Settings Profile.HopFrame.Testing.Api: https.executor": "Run", &quot;.NET Launch Settings Profile.HopFrame.Testing.Api: https.executor&quot;: &quot;Run&quot;,
".NET Launch Settings Profile.HopFrame.Testing.executor": "Run", &quot;.NET Launch Settings Profile.HopFrame.Testing.executor&quot;: &quot;Run&quot;,
".NET Launch Settings Profile.HopFrame.Testing: https.executor": "Run", &quot;.NET Launch Settings Profile.HopFrame.Testing: https.executor&quot;: &quot;Run&quot;,
".NET Project.HopFrame.Testing.executor": "Run", &quot;.NET Project.HopFrame.Testing.executor&quot;: &quot;Run&quot;,
"72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor": "Debug", &quot;72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor&quot;: &quot;Debug&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.git.unshallow": "true", &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
"b5f11219-dfc4-47a1-b02c-90ab603034fb.executor": "Debug", &quot;b5f11219-dfc4-47a1-b02c-90ab603034fb.executor&quot;: &quot;Debug&quot;,
"dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor": "Debug", &quot;dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor&quot;: &quot;Debug&quot;,
"git-widget-placeholder": "!30 on feature/plugins", &quot;git-widget-placeholder&quot;: &quot;!30 on feature/plugins&quot;,
"list.type.of.created.stylesheet": "CSS", &quot;list.type.of.created.stylesheet&quot;: &quot;CSS&quot;,
"node.js.detected.package.eslint": "true", &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
"node.js.detected.package.tslint": "true", &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
"node.js.selected.package.eslint": "(autodetect)", &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
"node.js.selected.package.tslint": "(autodetect)", &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
"nodejs_package_manager_path": "npm", &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
"settings.editor.selected.configurable": "preferences.environmentSetup", &quot;settings.editor.selected.configurable&quot;: &quot;preferences.environmentSetup&quot;,
"vue.rearranger.settings.migration": "true" &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
} }
}]]></component> }</component>
<component name="RunManager" selected=".NET Launch Settings Profile.HopFrame.Testing: https"> <component name="RunManager" selected=".NET Launch Settings Profile.HopFrame.Testing: https">
<configuration name="HopFrame.Testing: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile"> <configuration name="HopFrame.Testing: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" /> <option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" />
@@ -258,7 +239,8 @@
<workItem from="1738418482606" duration="2795000" /> <workItem from="1738418482606" duration="2795000" />
<workItem from="1738421294144" duration="1651000" /> <workItem from="1738421294144" duration="1651000" />
<workItem from="1738422949337" duration="141000" /> <workItem from="1738422949337" duration="141000" />
<workItem from="1738512801911" duration="6705000" /> <workItem from="1738512801911" duration="6776000" />
<workItem from="1738769458367" duration="962000" />
</task> </task>
<task id="LOCAL-00001" summary="Added basic configuration"> <task id="LOCAL-00001" summary="Added basic configuration">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -548,7 +530,15 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1738422931038</updated> <updated>1738422931038</updated>
</task> </task>
<option name="localTasksCounter" value="37" /> <task id="LOCAL-00037" summary="Added plugin events">
<option name="closed" value="true" />
<created>1738519603597</created>
<option name="number" value="00037" />
<option name="presentableId" value="LOCAL-00037" />
<option name="project" value="LOCAL" />
<updated>1738519603597</updated>
</task>
<option name="localTasksCounter" value="38" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -599,7 +589,6 @@
<component name="UnityProjectConfiguration" hasMinimizedUI="false" /> <component name="UnityProjectConfiguration" hasMinimizedUI="false" />
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" /> <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
<MESSAGE value="Added policy validation, ordering and virtual listing properties" />
<MESSAGE value="Added n -&gt; m relation support" /> <MESSAGE value="Added n -&gt; m relation support" />
<MESSAGE value="Added text area support and DI support for modifier functions" /> <MESSAGE value="Added text area support and DI support for modifier functions" />
<MESSAGE value="Addressed all build warnings" /> <MESSAGE value="Addressed all build warnings" />
@@ -624,6 +613,7 @@
<MESSAGE value="Added modular event system" /> <MESSAGE value="Added modular event system" />
<MESSAGE value="Fixed event emitter service scope" /> <MESSAGE value="Fixed event emitter service scope" />
<MESSAGE value="Added custom views" /> <MESSAGE value="Added custom views" />
<option name="LAST_COMMIT_MESSAGE" value="Added custom views" /> <MESSAGE value="Added plugin events" />
<option name="LAST_COMMIT_MESSAGE" value="Added plugin events" />
</component> </component>
</project> </project>

View File

@@ -1,5 +1,6 @@
@rendermode InteractiveServer @rendermode InteractiveServer
@implements IDialogContentComponent<EditorDialogData> @implements IDialogContentComponent<EditorDialogData>
@implements IDisposable
@using System.Collections @using System.Collections
@using HopFrame.Core.Config @using HopFrame.Core.Config
@@ -184,6 +185,7 @@
private ITableManager? _manager; private ITableManager? _manager;
private readonly Dictionary<string, List<string>> _validationErrors = new(); private readonly Dictionary<string, List<string>> _validationErrors = new();
private readonly List<PropertyChange> _changes = new(); private readonly List<PropertyChange> _changes = new();
private readonly CancellationTokenSource _tokenSource = new();
protected override void OnInitialized() { protected override void OnInitialized() {
_currentlyEditing = Content.CurrentObject is not null; _currentlyEditing = Content.CurrentObject is not null;
@@ -382,7 +384,7 @@
Errors = errorList, Errors = errorList,
Property = property, Property = property,
Table = Content.Config Table = Content.Config
}); }, _tokenSource.Token);
if (eventResult.IsCanceled) return false; if (eventResult.IsCanceled) return false;
} }
@@ -400,7 +402,11 @@
ApplyChanges(Content.CurrentObject!); ApplyChanges(Content.CurrentObject!);
return true; return true;
} }
public void Dispose() {
_tokenSource.Dispose();
}
private enum InputType { private enum InputType {
Number, Number,
Switch, Switch,

View File

@@ -158,6 +158,8 @@
private bool _allSelected; private bool _allSelected;
private readonly CancellationTokenSource _tokenSource = new();
protected override void OnInitialized() { protected override void OnInitialized() {
_config ??= Explorer.GetTable(TableDisplayName); _config ??= Explorer.GetTable(TableDisplayName);
@@ -206,7 +208,7 @@
var eventResult = await PluginOrchestrator.DispatchEvent(new SearchEvent(this) { var eventResult = await PluginOrchestrator.DispatchEvent(new SearchEvent(this) {
SearchTerm = _searchTerm, SearchTerm = _searchTerm,
Table = _config! Table = _config!
}); }, _tokenSource.Token);
if (eventResult.IsCanceled) return; if (eventResult.IsCanceled) return;
_searchTerm = eventResult.SearchTerm; _searchTerm = eventResult.SearchTerm;
@@ -218,7 +220,7 @@
var eventResult = await PluginOrchestrator.DispatchEvent(new ReloadEvent(this) { var eventResult = await PluginOrchestrator.DispatchEvent(new ReloadEvent(this) {
Table = _config! Table = _config!
}); }, _tokenSource.Token);
if (eventResult.IsCanceled) { if (eventResult.IsCanceled) {
_loading = false; _loading = false;
return; return;
@@ -240,7 +242,7 @@
NewPage = page, NewPage = page,
TotalPages = _totalPages, TotalPages = _totalPages,
Table = _config! Table = _config!
}); }, _tokenSource.Token);
if (eventResult.IsCanceled) return; if (eventResult.IsCanceled) return;
page = eventResult.NewPage; page = eventResult.NewPage;
@@ -258,7 +260,7 @@
var eventResult = await PluginOrchestrator.DispatchEvent(new DeleteEntryEvent(this) { var eventResult = await PluginOrchestrator.DispatchEvent(new DeleteEntryEvent(this) {
Entity = element, Entity = element,
Table = _config! Table = _config!
}); }, _tokenSource.Token);
if (eventResult.IsCanceled) return; if (eventResult.IsCanceled) return;
var dialog = await Dialogs.ShowConfirmationAsync("Do you really want to delete this entry?"); var dialog = await Dialogs.ShowConfirmationAsync("Do you really want to delete this entry?");
@@ -289,7 +291,7 @@
}; };
} }
var eventResult = await PluginOrchestrator.DispatchEvent(eventArgs); var eventResult = await PluginOrchestrator.DispatchEvent(eventArgs, _tokenSource.Token);
if (eventResult.IsCanceled) return; if (eventResult.IsCanceled) return;
var panel = await Dialogs.ShowPanelAsync<HopFrameEditor>(new EditorDialogData(_config!, element), new DialogParameters { var panel = await Dialogs.ShowPanelAsync<HopFrameEditor>(new EditorDialogData(_config!, element), new DialogParameters {
@@ -317,7 +319,7 @@
Entity = item, Entity = item,
Selected = selected, Selected = selected,
Table = _config! Table = _config!
}).Result; }, _tokenSource.Token).Result;
if (eventResult.IsCanceled) return; if (eventResult.IsCanceled) return;
selected = eventResult.Selected; selected = eventResult.Selected;

View File

@@ -1,5 +1,7 @@
namespace HopFrame.Web.Plugins; using HopFrame.Web.Plugins.Events;
namespace HopFrame.Web.Plugins;
public interface IPluginOrchestrator { public interface IPluginOrchestrator {
public Task<TEvent> DispatchEvent<TEvent>(TEvent @event, CancellationToken ct = new()); public Task<TEvent> DispatchEvent<TEvent>(TEvent @event, CancellationToken ct = new()) where TEvent : HopFrameEventArgs;
} }

View File

@@ -28,13 +28,25 @@ internal sealed class PluginOrchestrator(IServiceProvider services) : IPluginOrc
} }
} }
public async Task<TEvent> DispatchEvent<TEvent>(TEvent @event, CancellationToken ct = new()) { public async Task<TEvent> DispatchEvent<TEvent>(TEvent @event, CancellationToken ct = new()) where TEvent : HopFrameEventArgs {
var eventContainers = services.GetRequiredService<IEnumerable<PluginEventContainer>>() var eventContainers = services.GetRequiredService<IEnumerable<PluginEventContainer>>()
.Where(container => container.EventType == typeof(TEvent)); .Where(container => container.EventType == typeof(TEvent));
var eventType = typeof(TEvent);
var tokenType = typeof(CancellationToken);
foreach (var container in eventContainers) { foreach (var container in eventContainers) {
var plugin = services.GetRequiredService(container.Handler.DeclaringType!); var plugin = services.GetRequiredService(container.Handler.DeclaringType!);
var result = container.Handler.Invoke(plugin, [@event]); var parameters = new List<object?>();
foreach (var parameter in container.Handler.GetParameters()) {
if (parameter.ParameterType == eventType)
parameters.Add(@event);
else if (parameter.ParameterType == tokenType)
parameters.Add(ct);
else parameters.Add(null);
}
var result = container.Handler.Invoke(plugin, parameters.ToArray());
if (container.IsAwaitable) if (container.IsAwaitable)
await (Task)result!; await (Task)result!;