Files
speckle-sharp-connectors/DUI3/Speckle.Connectors.DUI/Bindings/SendOperationManager.cs
T
Adam Hathcock eb8db87d9f feat (Grasshopper) dev enable account auth by dev token (#937)
* adds url by token component

* Add gubbins for passing Account objects and AccountResource objects to include token usage

* format

* add bits to make things work?

* revert usage of SpeckleApplication

* review fixes

* more reverts

* Fix tests

* token is correct now

* fix build

* fixes url resource exception and adds new icon

* Made model cards dumb and moved conversions

* can build NW

* actually, remove dead code

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-25 08:42:37 +00:00

121 lines
4.1 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.InterfaceGenerator;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Logging;
namespace Speckle.Connectors.DUI.Bindings;
public partial interface ISendOperationManager : IDisposable;
[GenerateAutoInterface]
public sealed class SendOperationManager(
IServiceScope serviceScope,
IOperationProgressManager operationProgressManager,
DocumentModelStore store,
ICancellationManager cancellationManager,
ISpeckleApplication speckleApplication,
ISdkActivityFactory activityFactory,
IAccountManager accountManager,
ILogger<SendOperationManager> logger
) : ISendOperationManager
{
public async Task Process<T>(
ISendBindingUICommands commands,
string modelCardId,
Action<IServiceProvider, SenderModelCard> initializeScope,
Func<SenderModelCard, IReadOnlyList<T>> gatherObjects
)
{
await Process(commands, modelCardId, initializeScope, (card, _) => Task.FromResult(gatherObjects(card)));
}
public async Task Process<T>(
ISendBindingUICommands commands,
string modelCardId,
Action<IServiceProvider, SenderModelCard> initializeScope,
Func<SenderModelCard, Task<IReadOnlyList<T>>> gatherObjects
)
{
await Process(commands, modelCardId, initializeScope, async (card, _) => await gatherObjects(card));
}
public async Task Process<T>(
ISendBindingUICommands commands,
string modelCardId,
Action<IServiceProvider, SenderModelCard> initializeScope,
Func<SenderModelCard, IProgress<CardProgress>, Task<IReadOnlyList<T>>> gatherObjects
)
{
using var activity = activityFactory.Start();
try
{
if (store.GetModelById(modelCardId) is not SenderModelCard modelCard)
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No publish model card was found.");
}
using var cancellationItem = cancellationManager.GetCancellationItem(modelCardId);
initializeScope(serviceScope.ServiceProvider, modelCard);
var progress = operationProgressManager.CreateOperationProgressEventHandler(
commands.Bridge,
modelCardId,
cancellationItem.Token
);
var objects = await gatherObjects(modelCard, progress);
if (objects.Count == 0)
{
// Handle as CARD ERROR in this function
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
var sendInfo = GetSendInfo(modelCard);
var sendResult = await serviceScope
.ServiceProvider.GetRequiredService<ISendOperation<T>>()
.Execute(objects, sendInfo, progress, cancellationItem.Token);
await commands.SetModelSendResult(modelCardId, sendResult.VersionId, sendResult.ConversionResults);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
logger.LogModelCardHandledError(ex);
await commands.SetModelError(modelCardId, ex);
}
}
private SendInfo GetSendInfo(SenderModelCard modelCard)
{
var account = accountManager.GetAccount(modelCard.AccountId.NotNull());
return new(
account,
modelCard.ProjectId.NotNull(),
modelCard.ModelId.NotNull(),
speckleApplication.ApplicationAndVersion
);
}
[AutoInterfaceIgnore]
public void Dispose() => serviceScope.Dispose();
}