diff --git a/Changelog.md b/Changelog.md
index 0ce9f48..2d61ff5 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,6 +1,15 @@
# Changelog
*Below is the version history of [TrelloDotNet](https://github.com/rwjdk/TrelloDotNet) (An wrapper of the Trello API)*
+## 1.9.2 (12th of October 2023)
+#### General
+- All internal usage of `UpdateCardAsync` now uses the new 'partial update'-variant described below for better performance and more secure async usage in the Automation Engine
+
+#### TrelloClient
+- Added overload to [`UpdateCardAsync`](https://github.com/rwjdk/TrelloDotNet/wiki/UpdateCardAsync) that instead of a full update with a card can do partial updates with only the parameters you provide
+
+
+
## 1.9.1 (11th of October 2023)
#### Automation Engine
- Added Automation Trigger [`AddChecklistToCardTrigger`](https://github.com/rwjdk/TrelloDotNet/wiki/AddChecklistToCardTrigger)
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddCoverOnCardAction.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddCoverOnCardAction.cs
index a097023..373aed1 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddCoverOnCardAction.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddCoverOnCardAction.cs
@@ -1,6 +1,10 @@
-using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
using TrelloDotNet.AutomationEngine.Interface;
+using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
using TrelloDotNet.Model.Webhook;
namespace TrelloDotNet.AutomationEngine.Model.Actions
@@ -40,9 +44,10 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
throw new AutomationException("Could not perform AddCoverOnCardAction as WebhookAction did not involve a Card");
}
var trelloClient = webhookAction.TrelloClient;
- var card = await webhookAction.Data.Card.GetAsync();
- card.Cover = CardCoverToAdd;
- await trelloClient.UpdateCardAsync(card);
+ await trelloClient.UpdateCardAsync(webhookAction.Data.Card.Id, new List
+ {
+ new QueryParameter(CardFieldsType.Cover.GetJsonPropertyName(), JsonSerializer.Serialize(CardCoverToAdd))
+ });
processingResult.AddToLog($"Updated Card '{webhookAction.Data.Card.Name}' with new Cover");
processingResult.ActionsExecuted++;
}
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddLabelsToCardAction.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddLabelsToCardAction.cs
index a8ff57e..b30030b 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddLabelsToCardAction.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddLabelsToCardAction.cs
@@ -2,6 +2,9 @@
using System.Linq;
using System.Threading.Tasks;
using TrelloDotNet.AutomationEngine.Interface;
+using TrelloDotNet.Control;
+using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
using TrelloDotNet.Model.Webhook;
namespace TrelloDotNet.AutomationEngine.Model.Actions
@@ -77,7 +80,10 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
if (updateNeeded)
{
- await trelloClient.UpdateCardAsync(card);
+ await trelloClient.UpdateCardAsync(card.Id, new List()
+ {
+ new QueryParameter(CardFieldsType.LabelIds.GetJsonPropertyName(), card.LabelIds)
+ });
processingResult.AddToLog($"Added labels '{string.Join(",", LabelIds)}' to card '{webhookAction.Data.Card.Name}'");
processingResult.ActionsExecuted++;
}
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddMembersToCardAction.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddMembersToCardAction.cs
index ff70f95..e059598 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddMembersToCardAction.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/AddMembersToCardAction.cs
@@ -2,6 +2,9 @@
using System.Linq;
using System.Threading.Tasks;
using TrelloDotNet.AutomationEngine.Interface;
+using TrelloDotNet.Control;
+using TrelloDotNet.Model.Options;
+using TrelloDotNet.Model;
using TrelloDotNet.Model.Webhook;
namespace TrelloDotNet.AutomationEngine.Model.Actions
@@ -75,7 +78,10 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
if (updateNeeded)
{
- await trelloClient.UpdateCardAsync(card);
+ await trelloClient.UpdateCardAsync(card.Id, new List()
+ {
+ new QueryParameter(CardFieldsType.MemberIds.GetJsonPropertyName(), card.MemberIds)
+ });
processingResult.AddToLog($"Added members '{string.Join(",", MemberIds)}' to card '{webhookAction.Data.Card.Name}'");
processingResult.ActionsExecuted++;
}
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/ISetCardFieldValue.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/ISetCardFieldValue.cs
index 3e7c865..3c38166 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/ISetCardFieldValue.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/ISetCardFieldValue.cs
@@ -13,5 +13,12 @@ public interface ISetCardFieldValue
/// The Card to set the values on
/// If card was modified (aka need to be updated against the API)
bool SetIfNeeded(Card card);
+
+ ///
+ /// Get a Query Parameter representing the change (or null if not needed)
+ ///
+ /// Card to apply the change to
+ /// Query parameter of null
+ QueryParameter GetQueryParameter(Card card);
}
}
\ No newline at end of file
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCardDataAction.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCardDataAction.cs
index a98febf..225613a 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCardDataAction.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCardDataAction.cs
@@ -3,8 +3,10 @@
using System.Linq;
using System.Threading.Tasks;
using TrelloDotNet.AutomationEngine.Interface;
+using TrelloDotNet.Control;
using TrelloDotNet.Model;
using TrelloDotNet.Model.Actions;
+using TrelloDotNet.Model.Options;
using TrelloDotNet.Model.Webhook;
namespace TrelloDotNet.AutomationEngine.Model.Actions
@@ -41,7 +43,7 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
throw new AutomationException("Could not perform RemoveCardDataAction as WebhookAction did not involve a Card");
}
var card = await webhookAction.Data.Card.GetAsync();
- bool updateNeeded = false;
+ var queryParametersToUpdate = new List();
foreach (var dataType in DataToRemove)
{
switch (dataType)
@@ -50,49 +52,49 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
if (card.Start != null)
{
card.Start = null;
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.Start.GetJsonPropertyName(), (DateTimeOffset?)null));
}
break;
case RemoveCardDataType.DueDate:
if (card.Due != null)
{
card.Due = null;
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.Due.GetJsonPropertyName(), (DateTimeOffset?)null));
}
break;
case RemoveCardDataType.DueComplete:
if (card.DueComplete)
{
card.DueComplete = false;
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.DueComplete.GetJsonPropertyName(), false));
}
break;
case RemoveCardDataType.Description:
if (!string.IsNullOrWhiteSpace(card.Description))
{
card.Description = null;
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.Description.GetJsonPropertyName(), string.Empty));
}
break;
case RemoveCardDataType.AllLabels:
if (card.LabelIds.Any())
{
card.LabelIds = new List();
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.LabelIds.GetJsonPropertyName(), new List()));
}
break;
case RemoveCardDataType.AllMembers:
if (card.MemberIds.Any())
{
card.MemberIds = new List();
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.MemberIds.GetJsonPropertyName(), new List()));
}
break;
case RemoveCardDataType.Cover:
if (card.Cover != null && (card.Cover.Color != null || card.Cover.BackgroundImageId != null))
{
card.Cover = null;
- updateNeeded = true;
+ queryParametersToUpdate.Add(new QueryParameter(CardFieldsType.Cover.GetJsonPropertyName(), (string)null));
}
break;
case RemoveCardDataType.AllChecklists:
@@ -128,10 +130,10 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
}
}
- if (updateNeeded)
+ if (queryParametersToUpdate.Any())
{
processingResult.ActionsExecuted++;
- await webhookAction.TrelloClient.UpdateCardAsync(card);
+ await webhookAction.TrelloClient.UpdateCardAsync(card.Id, queryParametersToUpdate);
}
else
{
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCoverFromCardAction.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCoverFromCardAction.cs
index 3e7ac84..72f4ec7 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCoverFromCardAction.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/RemoveCoverFromCardAction.cs
@@ -1,5 +1,9 @@
-using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Threading.Tasks;
using TrelloDotNet.AutomationEngine.Interface;
+using TrelloDotNet.Control;
+using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
using TrelloDotNet.Model.Webhook;
namespace TrelloDotNet.AutomationEngine.Model.Actions
@@ -25,9 +29,10 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
throw new AutomationException("Could not perform RemoveCoverFromCardAction as WebhookAction did not involve a Card");
}
var trelloClient = webhookAction.TrelloClient;
- var card = await webhookAction.Data.Card.GetAsync();
- card.Cover = null;
- await trelloClient.UpdateCardAsync(card);
+ await trelloClient.UpdateCardAsync(webhookAction.Data.Card.Id, new List
+ {
+ new QueryParameter(CardFieldsType.Cover.GetJsonPropertyName(), (string)null)
+ });
processingResult.AddToLog($"Removed Cover from Card '{webhookAction.Data.Card.Name}'");
processingResult.ActionsExecuted++;
}
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDescriptionFieldValue.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDescriptionFieldValue.cs
index 191da88..62ca02c 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDescriptionFieldValue.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDescriptionFieldValue.cs
@@ -1,5 +1,7 @@
using System;
+using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet.AutomationEngine.Model.Actions
{
@@ -42,6 +44,12 @@ public bool SetIfNeeded(Card card)
return false;
}
+ ///
+ public QueryParameter GetQueryParameter(Card card)
+ {
+ return SetIfNeeded(card) ? new QueryParameter(CardFieldsType.Description.GetJsonPropertyName(), card.Description) : null;
+ }
+
///
/// Constructor
///
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueCompleteFieldValue.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueCompleteFieldValue.cs
index fff606e..4732839 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueCompleteFieldValue.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueCompleteFieldValue.cs
@@ -1,4 +1,6 @@
-using TrelloDotNet.Model;
+using TrelloDotNet.Control;
+using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet.AutomationEngine.Model.Actions
{
@@ -23,6 +25,12 @@ public bool SetIfNeeded(Card card)
return true;
}
+ ///
+ public QueryParameter GetQueryParameter(Card card)
+ {
+ return SetIfNeeded(card) ? new QueryParameter(CardFieldsType.DueComplete.GetJsonPropertyName(), card.DueComplete) : null;
+ }
+
///
/// Constructor
///
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueFieldValue.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueFieldValue.cs
index bdd1fef..aaa1fb9 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueFieldValue.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardDueFieldValue.cs
@@ -1,5 +1,7 @@
using System;
+using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet.AutomationEngine.Model.Actions
{
@@ -44,6 +46,12 @@ public bool SetIfNeeded(Card card)
return false;
}
+ ///
+ public QueryParameter GetQueryParameter(Card card)
+ {
+ return SetIfNeeded(card) ? new QueryParameter(CardFieldsType.Due.GetJsonPropertyName(), card.Due) : null;
+ }
+
///
/// Constructor
///
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardNameFieldValue.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardNameFieldValue.cs
index 4ae7a40..cd3d428 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardNameFieldValue.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardNameFieldValue.cs
@@ -1,5 +1,7 @@
using System;
+using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet.AutomationEngine.Model.Actions
{
@@ -44,6 +46,12 @@ public bool SetIfNeeded(Card card)
return false;
}
+ ///
+ public QueryParameter GetQueryParameter(Card card)
+ {
+ return SetIfNeeded(card) ? new QueryParameter(CardFieldsType.Name.GetJsonPropertyName(), card.Name) : null;
+ }
+
///
/// Constructor
///
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardStartFieldValue.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardStartFieldValue.cs
index 57baeb9..ba68c42 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardStartFieldValue.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetCardStartFieldValue.cs
@@ -1,5 +1,7 @@
using System;
+using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet.AutomationEngine.Model.Actions
{
@@ -43,6 +45,12 @@ public bool SetIfNeeded(Card card)
return false;
}
+ ///
+ public QueryParameter GetQueryParameter(Card card)
+ {
+ return SetIfNeeded(card) ? new QueryParameter(CardFieldsType.Start.GetJsonPropertyName(), card.Start) : null;
+ }
+
///
/// Constructor
///
diff --git a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetFieldsOnCardAction.cs b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetFieldsOnCardAction.cs
index 89b54bf..3283be0 100644
--- a/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetFieldsOnCardAction.cs
+++ b/TrelloDotNet/TrelloDotNet/AutomationEngine/Model/Actions/SetFieldsOnCardAction.cs
@@ -1,5 +1,8 @@
-using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
using TrelloDotNet.AutomationEngine.Interface;
+using TrelloDotNet.Model;
using TrelloDotNet.Model.Webhook;
namespace TrelloDotNet.AutomationEngine.Model.Actions
@@ -35,19 +38,21 @@ public async Task PerformActionAsync(WebhookAction webhookAction, ProcessingResu
throw new AutomationException("Could not perform SetFieldsOnCardAction as WebhookAction did not involve a Card");
}
var card = await webhookAction.Data.Card.GetAsync();
- bool updateNeeded = false;
+ var queryParametersToAdd = new List();
foreach (var fieldValue in FieldValues)
{
- if (fieldValue.SetIfNeeded(card))
+ QueryParameter queryParameter = fieldValue.GetQueryParameter(card);
+ if (queryParameter != null)
{
- updateNeeded = true;
+ queryParametersToAdd.Add(queryParameter);
}
+
}
- if (updateNeeded)
+ if (queryParametersToAdd.Any())
{
processingResult.ActionsExecuted++;
- await webhookAction.TrelloClient.UpdateCardAsync(card);
+ await webhookAction.TrelloClient.UpdateCardAsync(card.Id, queryParametersToAdd);
}
else
{
diff --git a/TrelloDotNet/TrelloDotNet/Control/QueryParametersBuilder.cs b/TrelloDotNet/TrelloDotNet/Control/QueryParametersBuilder.cs
index a1995ec..16993f8 100644
--- a/TrelloDotNet/TrelloDotNet/Control/QueryParametersBuilder.cs
+++ b/TrelloDotNet/TrelloDotNet/Control/QueryParametersBuilder.cs
@@ -62,7 +62,7 @@ internal QueryParameter[] GetViaQueryParameterAttributes(T instance)
else if (updateablePropertyType == typeof(List))
{
var list = (List)rawValue;
- parameters.Add(list == null ? new QueryParameter(jsonPropertyName.Name, string.Empty) : new QueryParameter(jsonPropertyName.Name, string.Join(",", list)));
+ parameters.Add(list == null ? new QueryParameter(jsonPropertyName.Name, string.Empty) : new QueryParameter(jsonPropertyName.Name, list));
}
else if (updateablePropertyType.BaseType == typeof(Enum))
{
diff --git a/TrelloDotNet/TrelloDotNet/Model/QueryParameter.cs b/TrelloDotNet/TrelloDotNet/Model/QueryParameter.cs
index cd38e42..5c398a8 100644
--- a/TrelloDotNet/TrelloDotNet/Model/QueryParameter.cs
+++ b/TrelloDotNet/TrelloDotNet/Model/QueryParameter.cs
@@ -1,6 +1,10 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
+using System.Text.Json;
+using TrelloDotNet.Control;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet.Model
{
@@ -31,6 +35,18 @@ public QueryParameter(string name, string value)
Type = QueryParameterType.String;
_valueAsObject = value;
}
+
+ ///
+ /// Constructor
+ ///
+ /// Name of the Parameter
+ /// Value of the Parameter
+ public QueryParameter(string name, List value)
+ {
+ Name = name;
+ Type = QueryParameterType.String;
+ _valueAsObject = value != null ? string.Join(",", value) : null;
+ }
///
/// Constructor
@@ -107,5 +123,10 @@ public string GetValueAsApiFormattedString()
throw new ArgumentOutOfRangeException();
}
}
+
+ internal string GetRawStringValue()
+ {
+ return _valueAsObject?.ToString();
+ }
}
}
\ No newline at end of file
diff --git a/TrelloDotNet/TrelloDotNet/TrelloClient.Cards.cs b/TrelloDotNet/TrelloDotNet/TrelloClient.Cards.cs
index 4b98027..068d7f5 100644
--- a/TrelloDotNet/TrelloDotNet/TrelloClient.Cards.cs
+++ b/TrelloDotNet/TrelloDotNet/TrelloClient.Cards.cs
@@ -4,8 +4,11 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using TrelloDotNet.AutomationEngine.Model;
+using TrelloDotNet.AutomationEngine.Model.Actions;
using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
using TrelloDotNet.Model.Options.GetCardOptions;
namespace TrelloDotNet
@@ -54,25 +57,35 @@ public async Task ReOpenCardAsync(string cardId, CancellationToken cancell
public async Task UpdateCardAsync(Card cardWithChanges, CancellationToken cancellationToken = default)
{
var parameters = _queryParametersBuilder.GetViaQueryParameterAttributes(cardWithChanges).ToList();
+ CardCover cardCover = cardWithChanges.Cover;
+ var payload = GeneratePayloadForCoverUpdate(cardCover, parameters);
+
+ return await _apiRequestController.PutWithJsonPayload($"{UrlPaths.Cards}/{cardWithChanges.Id}", cancellationToken, payload, parameters.ToArray());
+ }
+
+ private static string GeneratePayloadForCoverUpdate(CardCover cardCover, List parameters)
+ {
//Special code for Cover
string payload = string.Empty;
- if (cardWithChanges.Cover == null)
+ if (cardCover == null)
{
//Remove cover
parameters.Add(new QueryParameter("cover", ""));
}
else
{
- cardWithChanges.Cover.PrepareForAddUpdate();
- if (cardWithChanges.Cover.Color != null || cardWithChanges.Cover.BackgroundImageId != null)
+ cardCover.PrepareForAddUpdate();
+ if (cardCover.Color != null || cardCover.BackgroundImageId != null)
{
- parameters.Remove(parameters.First(x => x.Name == "idAttachmentCover")); //This parameter can't be there while a cover is added
+ QueryParameter queryParameter = parameters.FirstOrDefault(x => x.Name == "idAttachmentCover");
+ if (queryParameter != null)
+ {
+ parameters.Remove(queryParameter); //This parameter can't be there while a cover is added
+ }
}
-
- payload = $"{{\"cover\":{JsonSerializer.Serialize(cardWithChanges.Cover)}}}";
+ payload = $"{{\"cover\":{JsonSerializer.Serialize(cardCover)}}}";
}
-
- return await _apiRequestController.PutWithJsonPayload($"{UrlPaths.Cards}/{cardWithChanges.Id}", cancellationToken, payload, parameters.ToArray());
+ return payload;
}
///
@@ -247,10 +260,11 @@ public async Task> GetCardsForMemberAsync(string memberId, GetCardOpt
/// Cancellation Token
public async Task SetDueDateOnCardAsync(string cardId, DateTimeOffset dueDate, bool dueComplete = false, CancellationToken cancellationToken = default)
{
- var card = await GetCardAsync(cardId, cancellationToken);
- card.Due = dueDate;
- card.DueComplete = dueComplete;
- return await UpdateCardAsync(card, cancellationToken);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.Due.GetJsonPropertyName(), dueDate),
+ new QueryParameter(CardFieldsType.DueComplete.GetJsonPropertyName(), dueComplete)
+ }, cancellationToken);
}
///
@@ -261,9 +275,10 @@ public async Task SetDueDateOnCardAsync(string cardId, DateTimeOffset dueD
/// Cancellation Token
public async Task SetStartDateOnCardAsync(string cardId, DateTimeOffset startDate, CancellationToken cancellationToken = default)
{
- var card = await GetCardAsync(cardId, cancellationToken);
- card.Start = startDate;
- return await UpdateCardAsync(card, cancellationToken);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.Start.GetJsonPropertyName(), startDate)
+ }, cancellationToken);
}
///
@@ -276,11 +291,12 @@ public async Task SetStartDateOnCardAsync(string cardId, DateTimeOffset st
/// Cancellation Token
public async Task SetStartDateAndDueDateOnCardAsync(string cardId, DateTimeOffset startDate, DateTimeOffset dueDate, bool dueComplete = false, CancellationToken cancellationToken = default)
{
- var card = await GetCardAsync(cardId, cancellationToken);
- card.Start = startDate;
- card.Due = dueDate;
- card.DueComplete = dueComplete;
- return await UpdateCardAsync(card, cancellationToken);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.Start.GetJsonPropertyName(), startDate),
+ new QueryParameter(CardFieldsType.Due.GetJsonPropertyName(), dueDate),
+ new QueryParameter(CardFieldsType.DueComplete.GetJsonPropertyName(), dueComplete),
+ }, cancellationToken);
}
///
@@ -292,9 +308,31 @@ public async Task SetStartDateAndDueDateOnCardAsync(string cardId, DateTim
///
public async Task MoveCardToListAsync(string cardId, string newListId, CancellationToken cancellationToken = default)
{
- Card card = await GetCardAsync(cardId, cancellationToken);
- card.ListId = newListId;
- return await UpdateCardAsync(card, cancellationToken);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.ListId.GetJsonPropertyName(), newListId)
+ }, cancellationToken);
+ }
+
+ ///
+ /// Update one or more specific fields on a card (compared to a full update of all fields with UpdateCard)
+ ///
+ /// Id of the Card
+ /// The Specific Parameters to set
+ /// CancellationToken
+ public async Task UpdateCardAsync(string cardId, List parameters, CancellationToken cancellationToken = default)
+ {
+ QueryParameter coverParameter = parameters.FirstOrDefault(x => x.Name == "cover");
+ if (coverParameter != null && !string.IsNullOrWhiteSpace(coverParameter.GetRawStringValue()))
+ {
+ parameters.Remove(coverParameter);
+ CardCover cover = JsonSerializer.Deserialize(coverParameter.GetRawStringValue());
+ var payload = GeneratePayloadForCoverUpdate(cover, parameters);
+ return await _apiRequestController.PutWithJsonPayload($"{UrlPaths.Cards}/{cardId}", cancellationToken, payload, parameters.ToArray());
+ }
+
+ //Special Cover Card
+ return await _apiRequestController.Put($"{UrlPaths.Cards}/{cardId}", cancellationToken, parameters.ToArray());
}
}
}
\ No newline at end of file
diff --git a/TrelloDotNet/TrelloDotNet/TrelloClient.Labels.cs b/TrelloDotNet/TrelloDotNet/TrelloClient.Labels.cs
index 213c481..1517439 100644
--- a/TrelloDotNet/TrelloDotNet/TrelloClient.Labels.cs
+++ b/TrelloDotNet/TrelloDotNet/TrelloClient.Labels.cs
@@ -4,6 +4,7 @@
using System.Threading.Tasks;
using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet
{
@@ -44,11 +45,11 @@ public async Task AddLabelsToCardAsync(string cardId, params string[] labe
/// Add a Label to a Card
///
/// Id of the Card
- /// Cancellation Token
+ /// Cancellation Token
/// One or more Ids of Labels to add
- public async Task AddLabelsToCardAsync(string cardId, CancellationToken cancellation = default, params string[] labelIdsToAdd)
+ public async Task AddLabelsToCardAsync(string cardId, CancellationToken cancellationToken = default, params string[] labelIdsToAdd)
{
- var card = await GetCardAsync(cardId, cancellation);
+ var card = await GetCardAsync(cardId, cancellationToken);
var missing = labelIdsToAdd.Where(x => !card.LabelIds.Contains(x)).ToList();
if (missing.Count == 0)
@@ -58,7 +59,10 @@ public async Task AddLabelsToCardAsync(string cardId, CancellationToken ca
//Need update
card.LabelIds.AddRange(missing);
- return await UpdateCardAsync(card, cancellation);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.LabelIds.GetJsonPropertyName(), card.LabelIds)
+ }, cancellationToken);
}
///
@@ -88,7 +92,10 @@ public async Task RemoveLabelsFromCardAsync(string cardId, CancellationTok
//Need update
card.LabelIds = card.LabelIds.Except(toRemove).ToList();
- return await UpdateCardAsync(card, cancellationToken);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.LabelIds.GetJsonPropertyName(), card.LabelIds)
+ }, cancellationToken);
}
///
@@ -98,15 +105,10 @@ public async Task RemoveLabelsFromCardAsync(string cardId, CancellationTok
/// Cancellation Token
public async Task RemoveAllLabelsFromCardAsync(string cardId, CancellationToken cancellationToken = default)
{
- var card = await GetCardAsync(cardId, cancellationToken);
- if (card.LabelIds.Any())
+ return await UpdateCardAsync(cardId, new List
{
- //Need update
- card.LabelIds = new List();
- return await UpdateCardAsync(card, cancellationToken);
- }
-
- return card;
+ new QueryParameter(CardFieldsType.LabelIds.GetJsonPropertyName(), new List())
+ }, cancellationToken);
}
///
diff --git a/TrelloDotNet/TrelloDotNet/TrelloClient.Members.cs b/TrelloDotNet/TrelloDotNet/TrelloClient.Members.cs
index c0d6420..a6abdee 100644
--- a/TrelloDotNet/TrelloDotNet/TrelloClient.Members.cs
+++ b/TrelloDotNet/TrelloDotNet/TrelloClient.Members.cs
@@ -4,6 +4,7 @@
using System.Threading.Tasks;
using TrelloDotNet.Control;
using TrelloDotNet.Model;
+using TrelloDotNet.Model.Options;
namespace TrelloDotNet
{
@@ -70,7 +71,10 @@ public async Task AddMembersToCardAsync(string cardId, CancellationToken c
//Need update
card.MemberIds.AddRange(missing);
- return await UpdateCardAsync(card, cancellationToken);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.MemberIds.GetJsonPropertyName(), card.MemberIds)
+ }, cancellationToken);
}
///
@@ -87,11 +91,11 @@ public async Task RemoveMembersFromCardAsync(string cardId, params string[
/// Remove one or more Members from a Card
///
/// Id of the Card
- /// Cancellation Token
+ /// Cancellation Token
/// One or more Ids of Members to remove
- public async Task RemoveMembersFromCardAsync(string cardId, CancellationToken cancellation = default, params string[] memberIdsToRemove)
+ public async Task RemoveMembersFromCardAsync(string cardId, CancellationToken cancellationToken = default, params string[] memberIdsToRemove)
{
- var card = await GetCardAsync(cardId, cancellation);
+ var card = await GetCardAsync(cardId, cancellationToken);
var toRemove = memberIdsToRemove.Where(x => card.MemberIds.Contains(x)).ToList();
if (toRemove.Count == 0)
{
@@ -100,7 +104,10 @@ public async Task RemoveMembersFromCardAsync(string cardId, CancellationTo
//Need update
card.MemberIds = card.MemberIds.Except(toRemove).ToList();
- return await UpdateCardAsync(card, cancellation);
+ return await UpdateCardAsync(cardId, new List
+ {
+ new QueryParameter(CardFieldsType.MemberIds.GetJsonPropertyName(), card.MemberIds)
+ }, cancellationToken);
}
///
@@ -110,15 +117,10 @@ public async Task RemoveMembersFromCardAsync(string cardId, CancellationTo
/// Cancellation Token
public async Task RemoveAllMembersFromCardAsync(string cardId, CancellationToken cancellationToken = default)
{
- var card = await GetCardAsync(cardId, cancellationToken);
- if (card.MemberIds.Any())
+ return await UpdateCardAsync(cardId, new List
{
- //Need update
- card.MemberIds = new List();
- return await UpdateCardAsync(card, cancellationToken);
- }
-
- return card;
+ new QueryParameter(CardFieldsType.MemberIds.GetJsonPropertyName(), new List())
+ }, cancellationToken);
}
///
diff --git a/TrelloDotNet/TrelloDotNet/TrelloDotNet.csproj b/TrelloDotNet/TrelloDotNet/TrelloDotNet.csproj
index ad0b813..8d45200 100644
--- a/TrelloDotNet/TrelloDotNet/TrelloDotNet.csproj
+++ b/TrelloDotNet/TrelloDotNet/TrelloDotNet.csproj
@@ -13,7 +13,7 @@
https://github.com/rwjdk/TrelloDotNet/wiki
trello.png
trello api rest restful dotNet wrapper webhook automation
- 1.9.1
+ 1.9.2
RWJDK
MIT
https://github.com/rwjdk/TrelloDotNet/blob/main/Changelog.md