Skip to content

Commit ca3c37d

Browse files
committed
Remove TransformMenuItems from the plugin API
SidebarMenu doesn't support per-item OnSelect handlers, so non-app menu items injected by transformers were non-functional. Plugins should use AddApp instead.
1 parent 3c4a838 commit ca3c37d

7 files changed

Lines changed: 4 additions & 87 deletions

File tree

src/Ivy.Test/PluginLoaderTests.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -178,26 +178,6 @@ public void PluginDependencyPreventsUnload()
178178
}
179179
}
180180

181-
[Fact]
182-
public void MenuTransformersAreTrackedPerPlugin()
183-
{
184-
var context = new TestPluginContext();
185-
186-
context.SetCurrentPlugin("plugin-a", "/plugins/a");
187-
context.TransformMenuItems(items => items.Append(new MenuItem("A")));
188-
context.ClearCurrentPlugin();
189-
190-
context.SetCurrentPlugin("plugin-b", "/plugins/b");
191-
context.TransformMenuItems(items => items.Append(new MenuItem("B")));
192-
context.ClearCurrentPlugin();
193-
194-
Assert.Equal(2, context.MenuTransformers.Count);
195-
196-
// Unload plugin A
197-
context.RemovePluginContributions("plugin-a");
198-
199-
Assert.Single(context.MenuTransformers);
200-
}
201181

202182

203183
[Fact]

src/Ivy/Abstractions/IIvyExtendedPluginContext.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ public interface IIvyExtendedPluginContext : IIvyPluginContext
99
void AddApp(AppDescriptor descriptor);
1010
void AddAppsFromAssembly(Assembly assembly);
1111

12-
// Menu hooks
13-
void TransformMenuItems(Func<IEnumerable<MenuItem>, IEnumerable<MenuItem>> transformer, int priority = 0);
14-
1512
// ASP.NET pipeline
1613
void UseWebApplication(Action<WebApplication> configure);
1714
void UseWebApplicationBuilder(Action<WebApplicationBuilder> configure);

src/Ivy/AppShell/DefaultSidebarAppShell.cs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Ivy.Core;
22
using Ivy.Core.Apps;
33
using Ivy.Core.AppShell;
4-
using Ivy.Core.Plugins;
54
using System.Collections.Immutable;
65

76
// ReSharper disable once CheckNamespace
@@ -24,11 +23,10 @@ private record TabState(string Id, string AppId, string Title, AppHost AppHost,
2423
var appRepository = UseService<IAppRepository>();
2524
var client = UseService<IClientProvider>();
2625
Context.TryUseService<IAuthService>(out var auth);
27-
Context.TryUseService<IPluginMenuContributions>(out var pluginContributions);
2826
var user = UseState<UserInfo?>();
2927
var currentApp = UseState<AppHost?>();
3028
var search = UseState("");
31-
var menuItems = UseState(() => ApplyMenuTransformers(appRepository.GetMenuItems(), pluginContributions));
29+
var menuItems = UseState(() => appRepository.GetMenuItems());
3230

3331
// Auto-default: if there's exactly one visible app, select it and close sidebar
3432
var visibleApps = appRepository.GetMenuItems().FlattenWithPath().ToArray();
@@ -70,11 +68,11 @@ void SetAppTitle(string appId)
7068
{
7169
if (string.IsNullOrWhiteSpace(search.Value))
7270
{
73-
menuItems.Set(ApplyMenuTransformers(appRepository.GetMenuItems(), pluginContributions));
71+
menuItems.Set(appRepository.GetMenuItems());
7472
}
7573
else
7674
{
77-
var result = ApplyMenuTransformers(appRepository.GetMenuItems(), pluginContributions)
75+
var result = appRepository.GetMenuItems()
7876
.FlattenWithPath()
7977
.Select(x => new { x.Item, x.Path, Score = AppShellUtils.ItemMatchScore(x.Item, search.Value) })
8078
.Where(x => x.Score > 0)
@@ -561,16 +559,4 @@ void OnTabReorder(Event<TabsLayout, int[]> @event)
561559
settings.Width
562560
).Open(sidebarOpen.Value).MainAppSidebar(true);
563561
}
564-
565-
private static MenuItem[] ApplyMenuTransformers(MenuItem[] items, IPluginMenuContributions? contributions)
566-
{
567-
if (contributions is null) return items;
568-
var transformers = contributions.MenuTransformers;
569-
if (transformers.Count == 0) return items;
570-
571-
IEnumerable<MenuItem> result = items;
572-
foreach (var transformer in transformers)
573-
result = transformer(result);
574-
return result.ToArray();
575-
}
576562
}

src/Ivy/Core/Plugins/IPluginMenuContributions.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/Ivy/Core/Plugins/PluginContext.cs

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Ivy.Core.Plugins;
1212
/// This is an internal implementation detail of the plugin hosting infrastructure.
1313
/// Plugins should only depend on the <see cref="IIvyPluginContext"/> (or derived) interfaces.
1414
/// </summary>
15-
public abstract class PluginContextBase : IIvyExtendedPluginContext, IPluginServiceProvider, IPluginMenuContributions
15+
public abstract class PluginContextBase : IIvyExtendedPluginContext, IPluginServiceProvider
1616
{
1717
protected AppRepository AppRepository { get; }
1818
protected IReadOnlySet<string> ReservedPaths { get; }
@@ -31,7 +31,6 @@ protected PluginContextBase(AppRepository appRepository, IReadOnlySet<string> re
3131
ReservedPaths = reservedPaths;
3232
Builder = builder;
3333
}
34-
private readonly List<(Func<IEnumerable<MenuItem>, IEnumerable<MenuItem>> Transformer, int Priority)> _menuTransformers = [];
3534
private readonly List<Action<WebApplication>> _appActions = [];
3635
private readonly AggregatePluginServiceProvider _aggregateProvider = new();
3736
private readonly Dictionary<string, PluginState> _pluginStates = new();
@@ -59,23 +58,6 @@ public IServiceCollection Services
5958
internal void SetPluginConfig(IIvyPluginConfig config) => _currentPluginConfig = config;
6059
internal void ClearPluginConfig() => _currentPluginConfig = null;
6160

62-
public IReadOnlyList<Func<IEnumerable<MenuItem>, IEnumerable<MenuItem>>> MenuTransformers
63-
{
64-
get
65-
{
66-
_lock.EnterReadLock();
67-
try
68-
{
69-
return _menuTransformers
70-
.OrderBy(t => t.Priority)
71-
.Select(t => t.Transformer)
72-
.ToList();
73-
}
74-
finally { _lock.ExitReadLock(); }
75-
}
76-
}
77-
78-
7961
internal void SetCurrentPlugin(string pluginId, string directory)
8062
{
8163
_currentPluginId = pluginId;
@@ -111,20 +93,6 @@ public void AddAppsFromAssembly(Assembly assembly)
11193
state.AppFactories.Add(factory);
11294
}
11395

114-
public void TransformMenuItems(Func<IEnumerable<MenuItem>, IEnumerable<MenuItem>> transformer, int priority = 0)
115-
{
116-
_lock.EnterWriteLock();
117-
try
118-
{
119-
_menuTransformers.Add((transformer, priority));
120-
if (_currentPluginId is not null && _pluginStates.TryGetValue(_currentPluginId, out var state))
121-
state.MenuTransformers.Add((transformer, priority));
122-
}
123-
finally
124-
{
125-
_lock.ExitWriteLock();
126-
}
127-
}
12896

12997

13098
public void UseWebApplication(Action<WebApplication> configure)
@@ -206,9 +174,6 @@ internal virtual void RemovePluginContributions(string pluginId)
206174
// Collect app IDs before removing factories so we can reload affected sessions
207175
affectedAppIds = GetAppIdsFromFactories(state.AppFactories);
208176

209-
foreach (var t in state.MenuTransformers)
210-
_menuTransformers.Remove(t);
211-
212177
foreach (var a in state.AppActions)
213178
_appActions.Remove(a);
214179

src/Ivy/Core/Plugins/PluginState.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ internal class PluginState
99
public string Directory { get; }
1010
public ServiceCollection PluginServices { get; } = new();
1111

12-
public List<(Func<IEnumerable<MenuItem>, IEnumerable<MenuItem>> Transformer, int Priority)> MenuTransformers { get; } = [];
1312
public List<Action<WebApplication>> AppActions { get; } = [];
1413
public List<Func<AppDescriptor[]>> AppFactories { get; } = [];
1514

src/Ivy/Server.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,6 @@ public Server UsePlugins(
774774
_pluginLoader.Configure(pluginContext);
775775
pluginContext.BuildServiceProvider();
776776
builder.Services.AddSingleton<IPluginServiceProvider>(pluginContext);
777-
builder.Services.AddSingleton<IPluginMenuContributions>(pluginContext);
778777
builder.Services.AddSingleton<IPluginManager>(_pluginLoader);
779778
builder.Services.AddSingleton<IPluginStateService>(sp =>
780779
new PluginStateService(sp.GetRequiredService<IPluginManager>()));

0 commit comments

Comments
 (0)