This commit is contained in:
2026-06-02 17:13:26 +02:00
14 changed files with 474 additions and 25 deletions
+20
View File
@@ -0,0 +1,20 @@
using SharepointToolbox.Web.Core.Models;
namespace SharepointToolbox.Web.Services;
/// <summary>
/// Lists the document libraries of a single SharePoint site so users can pick a
/// library from a dropdown instead of typing its title by hand.
/// </summary>
public interface ILibraryDiscoveryService
{
/// <summary>
/// Returns the titles of the non-hidden document libraries on
/// <paramref name="siteUrl"/>, ordered case-insensitively by title.
/// Handles elevation + context creation internally.
/// </summary>
Task<IReadOnlyList<string>> ListLibrariesAsync(
TenantProfile profile,
string siteUrl,
CancellationToken ct = default);
}
+36
View File
@@ -0,0 +1,36 @@
using Microsoft.SharePoint.Client;
using SharepointToolbox.Web.Core.Helpers;
using SharepointToolbox.Web.Core.Models;
using SharepointToolbox.Web.Services.Session;
namespace SharepointToolbox.Web.Services;
public class LibraryDiscoveryService : ILibraryDiscoveryService
{
private readonly IElevationCoordinator _elevation;
private readonly ISessionManager _sessionManager;
public LibraryDiscoveryService(IElevationCoordinator elevation, ISessionManager sessionManager)
{
_elevation = elevation;
_sessionManager = sessionManager;
}
public async Task<IReadOnlyList<string>> ListLibrariesAsync(
TenantProfile profile, string siteUrl, CancellationToken ct = default)
{
if (string.IsNullOrWhiteSpace(siteUrl)) return Array.Empty<string>();
return await _elevation.RunAsync(async c =>
{
var ctx = await _sessionManager.GetOrCreateContextAsync(siteUrl, profile, c);
ctx.Load(ctx.Web, w => w.Lists.Include(l => l.Title, l => l.Hidden, l => l.BaseType));
await ExecuteQueryRetryHelper.ExecuteQueryRetryAsync(ctx, null, c);
return (IReadOnlyList<string>)ctx.Web.Lists
.Where(l => !l.Hidden && l.BaseType == BaseType.DocumentLibrary)
.Select(l => l.Title)
.OrderBy(t => t, StringComparer.OrdinalIgnoreCase)
.ToList();
}, ct);
}
}