Описание скриптов
Скрипт — это набор инструкций на C#, которые составляют тело скрытого внутреннего метода, затем компилируемого и выполняемого по триггерам.
Технически скрипты транслируются на внутренний промежуточный язык .NET - CIL.
Для работы скриптов открыт прямой доступ к Public API, используемый веб-клиент которого сгенерирован проектом Kiota.
Прямой доступ позволит пользователю писать уже сейчас все, что предоставляет публичный API.
Скрипты вызываются событиями в системе (триггеры CRUD для сущностей). На одно событие в рамках пространства может быть создано несколько скриптов.
Каждое событие имеет свой контекст - набор данных, связанный с ним: идентификаторы текущего пространства, пользователя, задачи, значения их полей и пр.
Контекст для разных событий отличается. Как объект он передаётся в память выполняющегося скрипта в виде типизированного объекта
(то есть, не содержит лишних свойств, а те что есть, сразу имеют правильный тип). Доступ осуществляется по краткому идентификатору “e
”.
Например: var userId = e.UserId
.
Сигнатуры методов имеют своими аргументами идентификаторы или имена/ключи задач, пространств, папок и т.д., там где это применимо, но они, как правило, необязательные. Если что-либо пропущено, то подразумевается текущее пространство, текущая задача и т.п., а для удобства использования они перечислены в порядке возрастания иерархии, то есть:
GetWorkitem(string? workitemKey = null, string? workspaceKey = null);
Функции-обертки
Метод, в котором выполняется пользовательский код, технически находится в
классе, наследуемом от базового класса, имеющей с одной стороны, веб-клиент
CwmPublicAPI
, а с другой - некоторые обертки над ним, более удобные для
пользовательского кода.
На данный момент реализованы следующие функции-обертки:
// *** CREATE ***
Task<WorkspaceModel> CreateWorkspace(string name, string key, string? description = null)
Task<FolderModel> CreateFolder(string name, Guid? parentId = null, string? workspaceKey = null)
Task<TypeModel> CreateType(CreateTypeRequestBody body, string? workspaceKey = null)
Task<StatusModel> CreateStatus(CreateStatusRequestBody body, string? workspaceKey = null)
Task<WorkitemModel> CreateWorkitem(CreateWorkitemRequestBody body, string? workspaceKey = null)
Task<CommentModel> CreateWorkitemComment(string text, string? workitemKey = null, string? workspaceKey = null)
Task<PortfolioModel> CreatePortfolio(string name, Guid folderId, string? workspaceKey = null)
Task<PortfolioElementModel> CreatePortfolioElement(CreatePortfolioElementRequestBody body, string? workspaceKey = null)
Task<RoleModel> CreateRole(string name, List<Permission?>? permissions, string? workspaceKey = null)
Task<AgileModel> CreateAgile(CreateAgileRequestBody body, string? workspaceKey = null)
Task<SprintModel> CreateSprint(CreateSprintRequestBody body, string? workspaceKey = null)
// атрибуты сейчас создаются только непривязанные - не позволяет Public API
Task<AttributeModel> CreateNumberAttribute(string name, string? description, string? workspaceKey = null)
Task<AttributeModel> CreateUniStringAttribute(string name, string? description = null, string? workspaceKey = null)
Task<AttributeModel> CreateUserAttribute(string name, string? description = null, string? workspaceKey = null)
Task<AttributeModel> CreateDateAttribute(string name, string? description = null, string? workspaceKey = null)
Task<AttributeModel> CreateTimeAttribute( string name, string? description = null, string? workspaceKey = null)
Task<AttributeModel> CreateUniSelectAttribute(string name, IEnumerable<string> listOptions, string? description = null, string? workspaceKey = null)
Task<AttributeModel> CreateTagAttribute(string name, LIEnumerablest<string> listOptions, string? description = null, string? workspaceKey = null)
// *** DELETE ***
Task DeleteWorkspace(string? workspaceKey = null)
Task DeleteFolder(Guid folderId, string? workspaceKey = null)
Task DeleteWorkitem(string? workitemKey = null, string? workspaceKey = null)
Task DeleteType(Guid typeId, string? workspaceKey = null)
Task DeleteType(string? type, string? workspaceKey = null)
Task DeleteAttribute(Guid attributeId, string? workspaceKey = null)
Task DeleteUserRole(Guid userId, Guid roleId, string? workspaceKey = null)
Task DeleteGroupRole(Guid groupId, Guid roleId, string? workspaceKey = null)
Task DeletePortfolio(Guid portfolioId, string? workspaceKey = null)
Task DeletePortfolioElement(Guid elementId, string? workspaceKey = null)
Task DeleteAgile(Guid agileExtensionId, string? workspaceKey = null)
Task DeleteSprint(Guid sprintId, string? workspaceKey = null)
Task DeleteAttachment(Guid attachmentId, string? workitemKey = null, string? workspaceKey = null)
// *** GET ***
Task<List<WorkspaceModel>?> GetWorkspaces()
Task<WorkspaceModel?> GetWorkspace(Guid workspaceId)
Task<WorkspaceModel?> GetWorkspace(string workspaceKey = null)
Task<List<FolderModel>?> GetFolders(string? workspaceKey = null)
Task<List<FolderModel>?> GetFolderByParent(Guid parentId, string? workspaceKey = null)
Task<FolderModel?> GetFolder(Guid folderId, string? workspaceKey = null)
Task<FolderModel?> GetFolder(string name, string? workspaceKey = null)
Task<List<WorkitemModel>?> GetWorkitems(string? workspaceKey = null)
Task<WorkitemModel?> GetWorkitem(Guid workitemId, string? workspaceKey = null)
Task<WorkitemModel?> GetWorkitem(string? workitemKey = null, string? workspaceKey = null)
Task<List<WorkitemModel>?> GetWorkitemByParent(bool withSubitems = false, string? parentKey = null, string? workspaceKey = null) // планарный список для иерархии потомков (withSubitems = true)
Task<WorkitemModelTree?> GetWorkitemTree(Guid? parentId = null, string? workspaceKey = null) // потомки в виде иерархического дерева, WorkitemModelTree - собственный тип ScriptAPI (https://git.testit.ru/teamstorm/teamstorm/-/blob/feature/ib/TS-8917-scripts-child-tasks/src/backend/dotnet/AutomationService.ScriptGate/Contracts/Tree.cs?ref_type=heads)
Task<List<AttachmentModel>?> GetWorkitemAttachments(string? workitemKey = null, string? workspaceKey = null)
Task<AttachmentModel?> GetWorkitemAttachment(Guid attachmentId, string? workitemKey = null, string? workspaceKey = null)
Task<List<CommentModel>?> GetWorkitemComments(string? workitemKey = null, string? workspaceKey = null)
Task<PortfolioModel> CreatePortfolio(string name, Guid folderId, string? workspaceKey = null)
Task<PortfolioElementModel> CreatePortfolioElement(CreatePortfolioElementRequestBody body, string? workspaceKey = null)
Task<List<UserModel>?> GetUsers()
Task<UserModel?> GetUser(Guid userId)
Task<UserModel?> GetUser(string userName)
Task<List<UserModel>?> GetUsersByRole(Guid roleId, string? workspaceKey = null)
Task<List<GroupModel>?> GetUsersGroups()
Task<GroupModel?> GetUserGroup(Guid userGroupId)
Task<List<GroupModel>?> GetUsersGroups(string userName)
Task<List<RoleModel>?> GetRoles(string? workspaceKey = null)
Task<List<RoleModel>?> GetRoles(bool? isSystem, string? workspaceKey = null)
Task<RoleModel?> GetRole(Guid roleId, string? workspaceKey = null)
Task<RoleModel?> GetRole(string role, string? workspaceKey = null)
Task<List<TypeModel>?> GetTypes(string? workspaceKey = null)
Task<TypeModel?> GetType(Guid typeId, string? workspaceKey = null)
Task<TypeModel?> GetType(string typeName, string? workspaceKey = null)
Task<List<LinkTypeModel>?> GetLinkTypes(string? workspaceKey = null)
Task<List<StatusCategoryModel>?> GetStatusCategories()
Task<List<StatusModel>?> GetStatuses(string? workspaceKey = null)
Task<StatusModel?> GetStatus(Guid statusId, string? workspaceKey = null)
Task<StatusModel?> GetStatus(string name, string? workspaceKey = null)
Task<List<AttributeModel>?> GetAttributes(string? workspaceKey = null)
Task<AttributeModel?> GetAttribute(Guid attributeId, string? workspaceKey = null)
Task<AttributeModel?> GetAttribute(string attributeName, string? workspaceKey = null)
Task<NumberFieldValueModel?> GetNumberAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<NumberFieldValueModel?> GetNumberAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<UniStringFieldValueModel?> GetUniStringAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<UniStringFieldValueModel?> GetUniStringAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<UniSelectFieldValueModel?> GetUniSelectAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<UniSelectFieldValueModel?> GetUniSelectAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<DateFieldValueModel?> GetDateAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<DateFieldValueModel?> GetDateAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<TimeFieldValueModel?> GetTimeAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<TimeFieldValueModel?> GetTimeAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<TagFieldValueModel?> GetTagAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<TagFieldValueModel?> GetTagAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<UserFieldValueModel?> GetUserAttributeValue(Guid attributeId, string? workitemKey = null, string? workspaceKey = null)
Task<UserFieldValueModel?> GetUserAttributeValue(string attributeName, string? workitemKey = null, string? workspaceKey = null)
Task<List<PortfolioModel>?> GetPortfolios(string? workspaceKey = null)
Task<List<PortfolioModel>?> GetPortfoliosInFolder(Guid folderId, string? workspaceKey = null)
Task<PortfolioModel?> GetPortfolio(Guid portfolioId, string? workspaceKey = null)
Task<PortfolioModel?> GetPortfolio(string name, string? workspaceKey = null)
Task<List<PortfolioElementModel>?> GetPortfolioElements(string? workspaceKey = null)
Task<List<PortfolioElementModel>?> GetPortfolioElementsInFolder(Guid folderId, string? workspaceKey = null)
Task<List<PortfolioElementModel>?> GetPortfolioElementsForStatus(string status, string? workspaceKey = null)
Task<List<PortfolioElementModel>?> GetPortfolioElements(Guid portfolioId, string? workspaceKey = null)
Task<PortfolioElementModel?> GetPortfolioElement(Guid elementId, string? workspaceKey = null)
Task<PortfolioElementModel?> GetPortfolioElement(string elementName, string? workspaceKey = null)
Task<List<WorkitemModel>?> GetWorkitemsByPortfolioElement(Guid elementId, string? workspaceKey = null)
Task<List<TimeTrackingEntryModel>?> GetTimeTrackingEntries(DateTime? startDate = null, DateTime? endDate = null,
List<string>? users = null, int? maxItemsCount = 50, string? fromToken = null)
Task<List<AgileModel>?> GetAgileExtensions(string? workspaceKey = null)
Task<AgileModel?> GetAgileExtension(Guid agileExtensionId, string? workspaceKey = null)
Task<List<SprintModel>?> GetSprints(string? workspaceKey = null)
Task<SprintModel?> GetSprint(Guid sprintId, string? workspaceKey = null)
Task<SprintModel?> GetSprint(string name, string? workspaceKey = null)
// *** UPDATE ***
Task<WorkspaceModel> UpdateWorkspaceName(string name, string? workspaceKey = null)
Task<FolderModel?> UpdateFolder(PatchFolderRequestBody body, Guid folderId, string? workspaceKey = null) // общего вида - сразу все свойства скопом
Task<WorkitemModel> UpdateFolderName(string name, Guid folderId, string? workspaceKey = null)
Task<PortfolioModel> UpdatePortfolio(Guid portfolioId, string name, string? workspaceKey = null)
Task<PortfolioElementModel> UpdatePortfolioElement(PortfolioElementModel body, string? workspaceKey = null)
Task<WorkitemModel?> UpdateWorkitem(PatchWorkitemRequestBody body, string? workitemKey = null, string? workspaceKey = null) // общего вида
Task<WorkitemModel> UpdateWorkitemParent(Guid? parentId, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemStatus(string status, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemType(string typeName, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemName(string name, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemDescription(string desc, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemAssignee(Guid userId, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemAssignee(string? userName, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemStartDate(DateTime? startDate, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemDueDate(DateTime? dueDate, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemSprint(Guid? sprintId, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemStoryPoints(int? points, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemOriginalEstimate(int? estimate, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemWorkflow(Guid? workflowId, string? workitemKey = null, string? workspaceKey = null)
Task<WorkitemModel> UpdateWorkitemPortfolioElement(List<Guid?>? elementIds, string? workitemKey = null, string? workspaceKey = null)
// атрибуты (только непривязанные - привязывать к типу воркайтема(задачи) не позволяет PublicAPI)
Task<AttributeModel> UpdateWorkitemAttribute(Guid attributeId, PatchAttributeRequestBody body, string? workspaceKey = null) // общего вида
Task<AttributeModel> UpdateScalarWorkitemAttribute(Guid attributeId, string name, string? description = null, string? workspaceKey = null) // все скалярные
Task<AttributeModel> UpdateListWorkitemAttribute(Guid attributeId, string name, List<PatchAttributeOptionModel> listOptions,
string? description = null, string? workspaceKey = null) // UniSelect & Tag
// значения атрибутов
Task<UniStringFieldValueModel?> UpdateUniStringAttributeValue(string attributeName, string value, string? workitemKey = null, string? workspaceKey = null)
Task<UniStringFieldValueModel?> UpdateUniStringAttributeValue(Guid attributeId, string value, string? workitemKey = null, string? workspaceKey = null)
Task<NumberFieldValueModel?> UpdateNumberAttributeValue(string attributeName, double? value, string? workitemKey = null, string? workspaceKey = null)
Task<NumberFieldValueModel?> UpdateNumberAttributeValue(Guid attributeId, double? value, string? workitemKey = null, string? workspaceKey = null)
Task<DateFieldValueModel?> UpdateDateAttributeValue(string attributeName, DateTime? value, string? workitemKey = null, string? workspaceKey = null)
Task<DateFieldValueModel?> UpdateDateAttributeValue(Guid attributeId, DateTime? value, string? workitemKey = null, string? workspaceKey = null)
Task<TimeFieldValueModel?> UpdateTimeAttributeValue(string attributeName, int? seconds, string? workitemKey = null, string? workspaceKey = null)
Task<TimeFieldValueModel?> UpdateTimeAttributeValue(Guid attributeId, int? seconds, string? workitemKey = null, string? workspaceKey = null)
Task<UserFieldValueModel?> UpdateUserAttributeValue(string attributeName, Guid userId, string? workitemKey = null, string? workspaceKey = null)
Task<UserFieldValueModel?> UpdateUserAttributeValue(Guid attributeId, Guid userId, string? workitemKey = null, string? workspaceKey = null)
Task<UniSelectFieldValueModel?> UpdateUniSelectAttributeValue(string attributeName, string option, string? workitemKey = null, string? workspaceKey = null)
Task<UniSelectFieldValueModel?> UpdateUniSelectAttributeValue(Guid attributeId, string option, string? workitemKey = null, string? workspaceKey = null)
Task<TagFieldValueModel?> UpdateTagAttributeValue(string attributeName, List<string> options, string? workitemKey = null, string? workspaceKey = null)
Task<TagFieldValueModel?> UpdateTagAttributeValue(Guid attributeId, List<string> options, string? workitemKey = null, string? workspaceKey = null)
// *** MISC ***
Task AddUserRole(Guid userId, Guid roleId, string? workspaceKey = null)
Task<RoleModel> UpdateRolePermissions(Guid roleId, List<Permission?>? permissions = null, string? workspaceKey = null)
// метод, позволяющий получать HTTP-доступ ко внешним Интернет-ресурсам (его безопасность управляется настройкам переменных окружения):
Task<string> SendHttpRequest(string url, HttpRequest request) // аргумент request содержит в себе все возможные свойства, передаваемые в следующей функции напрямую
Task<string> SendHttpRequest(string url, HttpMethod method = HttpMethod.Get, object? body = null,
List<(string Name, string Value)>? headers = null, string mediaType = "application/json",
IReadOnlyDictionary<string, object?>? options = null)
Примеры использования оберток см. в подразделе Примеры.
Примеры
Примечание
Для всех функций ScriptAPI (доступ к PublicAPI и логирование) необходимо указывать впереди ключевое слово await, так как они асинхронные.
Синтаксис языка — C11, поэтому инициализация коллекций происходит следующим образом: List<int> list = new { 1, 2 }, а не List<int> list = [ 1, 2 ]
.
Простейший пример скрипта, который даже не использует PublicAPI:
debug("USER = " + e.UserId);
Примечание
Если тело скрипта передается в запросе напрямую (на странице Swagger или утилите типа Postman), все внутренние двойные кавычки свойства, передаваемого JSON, необходимо экранировать:
{
Name: "Script1",
ScriptType: "Method",
EventType: "WorkitemNameChanged",
Script: "debug(\"USER = \" + e.UserId);", // вот тут в тексте самого скрипта - экранирование кавычек
}
Пример создания папки со случайным именем
var r = new Random();
var newName = $"name{r.Next(0, 1000)}";
await CreateFolder(newName); // вот тут должно быть await
debug("New name = " + newName);
Примеры скриптов, созданных через обертки
// Сравнение с текущим событием можно будет делать как по его Id, так и по его имени (enum лучше)
// Кейс 1: e.EventId == Events.WorkitemCreated (Events - класс с полями в виде именованных гуидов + некоторые вспомогательные функции)
// Кейс 2: e.EventType == EventTypes.WorkitemCreated (EventTypes - enum)
// Events также имеет статический словарь '<Guid, EventTypes> Map' - Id и enum события для системных полей
// Имена обсуждаемы
// Сценарий: автозаполнение исполнителя в зависимости от типа запроса
var wiType = await GetType(e.WorkitemTypeId);
if (e.EventType == EventTypes.WorkitemCreated && wiType.Name == "Bug") {
// UserModel? assignee = await GetUser("ivan.ivanov"); // в данном случае получение модели излишне
WorkitemModel? workitem = await UpdateWorkitemAssignee("ivan.ivanov");
}
// Сценарий: по умолчанию проставление среднего приоритета при регистрации запроса
var wiType = await GetType(e.WorkitemTypeId);
if (e.EventId == EventTypes.WorkitemCreated && wiType.Name == "Bug") {
// если уже имеется Id атрибута, лучше использовать функцию, принимающую именно его, а не имя (производительность)
await UpdateUniSelectAttributeValue("Приоритет", "Средний"); // текущий воркайтем
//await SetUniSelectAttributeValue(attributeId, "Средний", workitemId2); // сторонний воркайтем, но текущего воркспейса
//await SetUniSelectAttributeValue(attributeId, "Средний", workitemId2, workspaceId2); // воркайтем в стороннем воркспейсе
}
// Сценарий: проставление команды в зависимости от исполнителя
var user = await GetUser(e.WorkitemAssigneeId);
// 'WorkitemChanged' нет - все события на изменение гранулярные
if (e.EventType == EventTypes.WorkitemNameChanged && user.Username == "ivan.ivanov") {
await UpdateUniSelectAttributeValue("Команда", "Alfa");
}
// Сценарий: Автоматическое назначение на задачу определенной проектной роли. Как следствие назначается пользователь, у которого установлена такая проектная роль.
List<UserModel> users = await GetUsersByRole(roleId); // можно так (все функции планарно на одном уровне, но функции могут быть длиннее по имени - с префиксом сущности)
// List<UserModel> users = await WorkspaceUsers.FindByRole(role); // а можно эдак (в АПИ организовать отдельные 'свойства доступа': для текущего воркайтема, общего доступа в воркспейсам, юзерам и т.д.)
// Сценарий: Автоматическое присвоение типа документа по вхождению определенного текста в название документа.
// Сценарий: Создание задачи с автоматическим определением типа на базе локации пользователя, то есть где пользователь инициировал создание задачи. Чаще всего применимо к спискам (портфолио).
WorkitemModel wi = await UpdateWorkitemType("SomeType"); // текущему воркайтему
// Сценарий: Расчет и заполнение атрибута в зависимости от значений других атрибутов текущей задачи. Например, автоматическое присваивание задаче портфолио, если она является определенного типа.
PortfolioElementModel? elem1 = await GetPortfolioElement(elementId);
PortfolioElementModel? elem1 = await GetPortfolioElement("Element1"); // или по elementName
// PorfolioElementModel? elem1 = await PorfolioElements.FindByName(name); // либо так
elem1.StartDate = DateTimeOffset.UtcNow.AddDays(10).Date; // изменить сам элемент
await UpdatePortfolioElement(elem1);
await UpdateWorkitemPortfolioElements(elementIds); // привязка к воркайтему списка элементов портфолио - по гуидам
// Сценарий: Установить ответственного при определённых значениях
var priorityValue = await GetUniSelectAttributeValue(priorityAttributeName);
var tagValue = await GetTagAttributeValue(tagAttributeName); // текущий воркайтем
if (priorityValue.Value.Name == "Высокий" && tagValue.Value.Any(a => a.Name == "UX")) {
await UpdateWorkitemAssignee(userId); // текущему воркайтему!
}
// Автоматически рассчитать стоимость задачи и записать результат в атрибут "Общая стоимость", перемножив значения атрибутов "Оценка в часах" и "Стоимость часа".
NumberFieldValueModel attr1 = await GetNumberAttributeValue("Оценка в часах");
NumberFieldValueModel attr2 = await GetNumberAttributeValue("Стоимость часа");
if(attr1.Value != null && attr2.Value != null)
{
var val3 = attr1.Value * attr2.Value;
await UpdateNumberAttributeValue("Общая стоимость", val3);
}
// Автоматически рассчитать сумму атрибутов “Оценка” во всех дочерних задачах и заполнить рассчитанным значением атрибута “Оценка“ в родительской задаче.
var tree = await GetWorkitemTree();
List<WorkitemModel> sons = tree.GetChildren();
var result = 0.0;
foreach (var son in sons)
{
var attribute = son.Attributes.Single(a => a.NumberFieldValueModel.Name == "Оценка");
result += attribute.NumberFieldValueModel.Value ?? 0;
}
await UpdateNumberAttributeValue("Оценка", result);
Примеры создания скриптов напрямую
// Пример обёртки создания пространства
public async Task<WorkspaceModel> CreateWorkspace(string name, string key, string? description = null)
{
var response = await Latest
.Workspaces
.PostAsync(new CreateWorkspaceRequestBody
{
Key = key,
Name = name,
Description = description,
});
if (response is null)
{
throw new OperationFailedException($"Failed to create the workspace with name [{name}] and key [{key}]");
}
return response;
}
// создание задачи (при этом заранее создаём объект задачи в body)
public async Task<WorkitemModel> CreateWorkitem(CreateWorkitemRequestBody body, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
return await Latest
.Workspaces[workspaceKey]
.Workitems
.PostAsync(body);
}
// создание комментария к задаче
public async Task<CommentModel> CreateWorkitemComment(string text, string? workitemKey = null, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
CheckWorkitemKey(ref workitemKey);
var body = new CreateCommentRequestBody { Text = text };
return await Latest
.Workspaces[workspaceKey]
.Workitems[workitemKey]
.Comments
.PostAsync(body);
}
// получение пространств
public async Task<List<WorkspaceModel>?> GetWorkspaces()
{
var response = await Latest
.Workspaces
.GetAsync();
return response?.Items;
}
// Получение модели папки
public async Task<FolderModel?> GetFolder(Guid folderId, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
return await Latest
.Workspaces[workspaceKey]
.Folders[folderId]
.GetAsync();
}
// Получение статусов
public async Task<List<StatusModel>?> GetStatuses(string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
var response = await Latest
.Workspaces[workspaceKey]
.Statuses
.GetAsync();
return response?.Items;
}
// получение атрибута
public async Task<AttributeModel?> GetAttribute(string attributeName, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
var response = await Latest
.Workspaces[workspaceKey]
.Attributes
.GetAsync(x =>
x.QueryParameters.Name = attributeName);
return response?.Items?.FirstOrDefault();
}
// Получение значений атрибутов указанной задачи:
AttributeValueModelList? response = await Latest
.Workspaces[workspaceKey]
.Workitems[workitemKey]
.Attributes
.GetAsync();
return response;
// Изменение имени задачи:
var body = new PatchWorkitemRequestBody { Name = name };
var patchResponse = await Latest
.Workspaces[workspaceKey]
.Workitems[workitemKey]
.PatchAsync(body);
// изменение значения атрибута типа "Время" для указанной задачи
public async Task<TimeFieldValueModel?> UpdateTimeAttributeValue(Guid attributeId, int? seconds,
string? workitemKey = null, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
CheckWorkitemKey(ref workitemKey);
var body = new WithAttributeItemRequestBuilder.WithAttributePutRequestBody
{
UpdateTimeFieldRequestBody = new UpdateTimeFieldRequestBody
{
Type = AttributeType.TimeDuration,
Value = seconds,
},
};
var response = await Latest
.Workspaces[workspaceKey]
.Workitems[workitemKey]
.Attributes[attributeId]
.PutAsync(body);
return response?.TimeFieldValueModel;
}
// Изменение портфолио (по факту - просто имени):
public async Task<PortfolioModel> UpdatePortfolio(Guid portfolioId, string name, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
var patchResponse = await Latest
.Workspaces[workspaceKey]
.Portfolios[portfolioId]
.PatchAsync(new PatchPortfolioRequestBody
{
Name = name,
});
if (patchResponse is null)
{
throw new OperationFailedException($"Failed to update the portfolio in workspace {workspaceKey}");
}
return patchResponse;
}
// добавить роль пользователю:
public async Task AddUserRole(Guid userId, Guid roleId, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
await Latest
.Workspaces[workspaceKey]
.Users[userId]
.Roles[roleId]
.PostAsync();
}
// Удаление атрибута:
public async Task DeleteAttribute(Guid attributeId, string? workspaceKey = null)
{
CheckWorkspaceKey(ref workspaceKey);
await Latest
.Workspaces[workspaceKey]
.Attributes[attributeId]
.DeleteAsync();
}