Feat(gh): Add optional version message for senders (#986)

* Add optional version message for senders

* Rework to not have optional parameters

---------

Co-authored-by: Adam Hathcock <adam@hathcock.uk>
This commit is contained in:
Oğuzhan Koral
2025-07-16 17:37:13 +03:00
committed by GitHub
parent e130045930
commit b88f50ced6
8 changed files with 53 additions and 13 deletions
@@ -25,9 +25,6 @@ namespace Speckle.Connectors.GrasshopperShared.Components.Operations.Send;
[Guid("52481972-7867-404F-8D9F-E1481183F355")]
public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
{
public GhContextMenuButton ProjectContextMenuButton { get; set; }
public GhContextMenuButton ModelContextMenuButton { get; set; }
public SendAsyncComponent()
: base(
"Publish",
@@ -57,6 +54,8 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
public SpeckleUrlModelResource? OutputParam { get; set; }
public bool HasMultipleInputs { get; set; }
public string? VersionMessage { get; private set; }
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam());
@@ -67,6 +66,8 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
"The collection model object to send",
GH_ParamAccess.item
);
pManager.AddTextParameter("Version Message", "versionMessage", "The version message", GH_ParamAccess.item);
pManager[2].Optional = true;
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
@@ -275,6 +276,10 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
return;
}
RootCollectionWrapper = rootCollectionWrapper;
string? versionMessage = null;
da.GetData(2, ref versionMessage);
VersionMessage = versionMessage;
}
}
@@ -402,7 +407,13 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
using var scope = PriorityLoader.CreateScopeForActiveDocument();
var sendOperation = scope.ServiceProvider.GetRequiredService<SendOperation<SpeckleCollectionWrapperGoo>>();
SendOperationResult? result = await sendOperation
.Execute(new List<SpeckleCollectionWrapperGoo>() { rootCollectionWrapper }, sendInfo, progress, CancellationToken)
.Execute(
new List<SpeckleCollectionWrapperGoo>() { rootCollectionWrapper },
sendInfo,
Parent.VersionMessage,
progress,
CancellationToken
)
.ConfigureAwait(false);
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
@@ -49,6 +49,8 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
public string? Url { get; private set; }
public string? VersionMessage { get; private set; }
protected override Bitmap Icon => Resources.speckle_operations_syncpublish;
protected override void RegisterInputParams(GH_InputParamManager pManager)
@@ -61,7 +63,8 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
"The model collection to publish",
GH_ParamAccess.item
);
pManager.AddTextParameter("Version Message", "versionMessage", "The version message", GH_ParamAccess.item);
pManager[2].Optional = true;
pManager.AddBooleanParameter("Run", "r", "Run the publish operation", GH_ParamAccess.item);
}
@@ -86,8 +89,12 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
SpeckleCollectionWrapperGoo rootCollectionWrapper = new();
da.GetData(1, ref rootCollectionWrapper);
string? versionMessage = null;
da.GetData(2, ref versionMessage);
VersionMessage = versionMessage;
bool run = false;
da.GetData(2, ref run);
da.GetData(3, ref run);
return new SendComponentInput(resource.NotNull(), rootCollectionWrapper, run);
}
@@ -177,8 +184,14 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
using var client = clientFactory.Create(account);
var sendInfo = await input.Resource.GetSendInfo(client, cancellationToken).ConfigureAwait(false);
var result = await sendOperation
.Execute(new List<SpeckleCollectionWrapperGoo>() { input.Input }, sendInfo, progress, cancellationToken)
await sendOperation
.Execute(
new List<SpeckleCollectionWrapperGoo>() { input.Input },
sendInfo,
VersionMessage,
progress,
cancellationToken
)
.ConfigureAwait(false);
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
@@ -81,7 +81,7 @@ public class SendOperationManagerTests : MoqTest
var sendOperationMock = Create<ISendOperation<string>>();
sendOperationMock
.Setup(x => x.Execute(objects, It.IsAny<SendInfo>(), progressHandler.Object, It.IsAny<CancellationToken>()))
.Setup(x => x.Execute(objects, It.IsAny<SendInfo>(), null, progressHandler.Object, It.IsAny<CancellationToken>()))
.ReturnsAsync(
new SendOperationResult("rootObjId", versionId, new Dictionary<Id, ObjectReference>(), sendResults)
);
@@ -86,7 +86,7 @@ public sealed class SendOperationManager(
var sendResult = await serviceScope
.ServiceProvider.GetRequiredService<ISendOperation<T>>()
.Execute(objects, sendInfo, progress, cancellationItem.Token);
.Execute(objects, sendInfo, null, progress, cancellationItem.Token);
await commands.SetModelSendResult(modelCardId, sendResult.VersionId, sendResult.ConversionResults);
}
@@ -46,6 +46,7 @@ public class Sender(
projectId,
modelId,
token,
null,
account,
progress,
CancellationToken.None
@@ -71,7 +71,7 @@ public class SendOperationTests : MoqTest
activityFactory.Object,
threadContext.Object
);
var result = await sendOperation.Execute(objects, sendInfo, progress.Object, ct);
var result = await sendOperation.Execute(objects, sendInfo, null, progress.Object, ct);
result.Should().NotBeNull();
rootResult.RootObject["version"].Should().Be(3);
result.RootObjId.Should().Be(rootId);
@@ -125,7 +125,7 @@ public class SendOperationTests : MoqTest
sendProgress.Setup(x => x.Begin());
sendOperationVersionRecorder
.Setup(x => x.RecordVersion(rootId, modelId, projectId, sourceApplication, account, ct))
.Setup(x => x.RecordVersion(rootId, modelId, projectId, sourceApplication, null, account, ct))
.ReturnsAsync("version");
var sp = services.BuildServiceProvider();
@@ -145,6 +145,7 @@ public class SendOperationTests : MoqTest
projectId,
modelId,
sourceApplication,
null,
account,
progress.Object,
ct
@@ -26,6 +26,7 @@ public sealed class SendOperation<T>(
public async Task<SendOperationResult> Execute(
IReadOnlyList<T> objects,
SendInfo sendInfo,
string? versionMessage,
IProgress<CardProgress> onOperationProgressed,
CancellationToken ct = default
)
@@ -41,6 +42,7 @@ public sealed class SendOperation<T>(
sendInfo.ProjectId,
sendInfo.ModelId,
sendInfo.SourceApplication,
versionMessage,
sendInfo.Account,
onOperationProgressed,
ct
@@ -70,6 +72,7 @@ public sealed class SendOperation<T>(
string projectId,
string modelId,
string sourceApplication,
string? versionMessage,
Account account,
IProgress<CardProgress> onOperationProgressed,
CancellationToken ct = default
@@ -103,6 +106,7 @@ public sealed class SendOperation<T>(
modelId,
projectId,
sourceApplication,
versionMessage,
account,
ct
);
@@ -13,13 +13,23 @@ public class SendOperationVersionRecorder(IClientFactory clientFactory) : ISendO
string modelId,
string projectId,
string sourceApplication,
string? versionMessage,
Account account,
CancellationToken ct
)
{
using var apiClient = clientFactory.Create(account);
var x = await apiClient
.Version.Create(new CreateVersionInput(rootId, modelId, projectId, sourceApplication: sourceApplication), ct)
.Version.Create(
new CreateVersionInput(
rootId,
modelId,
projectId,
sourceApplication: sourceApplication,
message: versionMessage
),
ct
)
.ConfigureAwait(true);
return x.id;
}