Skip to content

Commit 95f5744

Browse files
committed
➕ ICTime GetAvailableActivities() (maybe not yet working; we'll see in live)
1 parent 6f54bbb commit 95f5744

File tree

5 files changed

+103
-8
lines changed

5 files changed

+103
-8
lines changed

jwl.jira/IJiraClient.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ public interface IJiraClient
99
{
1010
api.rest.common.JiraUserInfo UserInfo { get; }
1111

12-
Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(string issueKey);
12+
Task<WorkLogType[]> GetAvailableActivities(string issueKey);
13+
14+
Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnumerable<string> issueKeys);
1315

1416
Task<WorkLog[]> GetIssueWorklogs(DateOnly from, DateOnly to, string issueKey);
1517

jwl.jira/JiraWithICTimePluginApi.cs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
namespace jwl.jira;
22

3+
using System.Diagnostics;
34
using System.Net.Http.Json;
5+
using System.Xml.Linq;
46
using System.Xml.Serialization;
57
using jwl.infra;
68
using jwl.wadl;
79

810
// https://interconcept.atlassian.net/wiki/spaces/ICTIME/pages/31686672/API
911
// https://interconcept.atlassian.net/wiki/spaces/ICBIZ/pages/34701333/REST+Services
10-
// {{JiraBaseURI}}/rest/ictime/1.0/application.wadl
1112
public class JiraWithICTimePluginApi
1213
: IJiraClient
1314
{
@@ -38,9 +39,75 @@ public JiraWithICTimePluginApi(HttpClient httpClient, string userName)
3839
_vanillaJiraApi = new VanillaJiraClient(httpClient, userName);
3940
}
4041

41-
public async Task<WorkLogType[]> GetAvailableActivities()
42+
public async Task<WorkLogType[]> GetAvailableActivities(string issueKey)
4243
{
43-
return await _vanillaJiraApi.GetAvailableActivities();
44+
var result = await GetAvailableActivities(new string[] { issueKey });
45+
return result[issueKey];
46+
}
47+
48+
public async Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnumerable<string> issueKeys)
49+
{
50+
IEnumerable<JiraIssueKey> issueKeysParsed = issueKeys
51+
.Select(issueKey => new JiraIssueKey(issueKey))
52+
.ToArray();
53+
54+
IEqualityComparer<JiraIssueKey> projectComparer = new JiraIssueKey.ProjectOnlyEqualityComparer();
55+
IEnumerable<JiraIssueKey> distinctProjects = issueKeysParsed
56+
.Distinct(projectComparer);
57+
58+
ComposedWadlMethodDefinition endPoint = GetActivityTypesForProjectMethodDefinition;
59+
60+
HashSet<string> missingParameters = endPoint.Parameters
61+
.Where(par => !string.IsNullOrEmpty(par.Name))
62+
.Select(par => par.Name ?? string.Empty)
63+
.ToHashSet();
64+
65+
// define
66+
IEnumerable<KeyValuePair<JiraIssueKey, string>> uris = distinctProjects
67+
.Select(issueKey => new KeyValuePair<JiraIssueKey, string>(issueKey, endPoint.ResourcePath.Replace("{issueKey}", issueKey.ToString())));
68+
69+
missingParameters.Remove("issueKey");
70+
71+
// check
72+
if (missingParameters.Any())
73+
throw new ArgumentNullException($"Missing assignment of {string.Join(',', missingParameters)} in the call of {endPoint.Id} at resource path {endPoint.ResourcePath}");
74+
75+
bool providesJsonResponses = endPoint.Response?.Representations?
76+
.Any(repr => repr.MediaType == WadlRepresentation.MediaTypes.Json) ?? false;
77+
78+
if (providesJsonResponses)
79+
throw new InvalidDataException($"Method {endPoint.Id} at resource path {endPoint.ResourcePath} does not respond in JSON");
80+
81+
// execute
82+
KeyValuePair<JiraIssueKey, Task<api.rest.response.ICTimeActivityDefinition[]>>[] responseTaks = uris
83+
.Select(uri => new KeyValuePair<JiraIssueKey, Task<api.rest.response.ICTimeActivityDefinition[]>>(uri.Key, _httpClient.GetAsJsonAsync<api.rest.response.ICTimeActivityDefinition[]>(uri.Value)))
84+
.ToArray();
85+
86+
await Task.WhenAll(responseTaks.Select(x => x.Value));
87+
88+
Dictionary<string, WorkLogType[]> result = responseTaks
89+
.Join(
90+
inner: issueKeysParsed,
91+
outerKeySelector: outer => outer.Key,
92+
innerKeySelector: inner => inner,
93+
resultSelector: (outer, inner) => new KeyValuePair<string, WorkLogType[]>(
94+
outer.Key.ToString(),
95+
outer.Value.Result
96+
.Select((def, ix) => new WorkLogType(
97+
Key: def.Id.ToString(),
98+
Value: def.Name,
99+
Sequence: ix
100+
))
101+
.ToArray()
102+
),
103+
comparer: projectComparer
104+
)
105+
.ToDictionary(
106+
keySelector: x => x.Key,
107+
elementSelector: x => x.Value
108+
);
109+
110+
return result;
44111
}
45112

46113
public async Task<WorkLog[]> GetIssueWorklogs(DateOnly from, DateOnly to, string issueKey)

jwl.jira/JiraWithTempoPluginApi.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ public JiraWithTempoPluginApi(HttpClient httpClient, string userName)
2828
return await _httpClient.GetAsJsonAsync<api.rest.response.TempoWorklogAttributeDefinition[]>(@"rest/tempo-core/1/work-attribute");
2929
}
3030

31-
public async Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnumerable<string> issueKeys)
31+
public async Task<WorkLogType[]> GetAvailableActivities(string issueKey)
3232
{
3333
api.rest.response.TempoWorklogAttributeDefinition[] attrEnumDefs = await GetWorklogAttributeDefinitions();
3434

35-
WorkLogType[] activities = attrEnumDefs
35+
WorkLogType[] result = attrEnumDefs
3636
.Where(attrDef => attrDef.Key?.Equals(WorklogTypeAttributeKey) ?? false)
3737
.Where(attrDef => attrDef.Type != null
3838
&& attrDef.Type?.Value == TempoWorklogAttributeTypeIdentifier.StaticList
@@ -46,6 +46,13 @@ public async Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnu
4646
))
4747
.ToArray();
4848

49+
return result;
50+
}
51+
52+
public async Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnumerable<string> issueKeys)
53+
{
54+
WorkLogType[] activities = await GetAvailableActivities(string.Empty);
55+
4956
Dictionary<string, WorkLogType[]> result = issueKeys
5057
.Select(issueKey => new ValueTuple<string, WorkLogType[]>(issueKey, activities))
5158
.ToDictionary(

jwl.jira/VanillaJiraClient.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,15 @@ public static async Task CheckHttpResponseForErrorMessages(HttpResponseMessage r
3838
}
3939

4040
#pragma warning disable CS1998
41+
public async Task<WorkLogType[]> GetAvailableActivities(string issueKey)
42+
{
43+
return Array.Empty<WorkLogType>();
44+
}
45+
#pragma warning restore
46+
4147
public async Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnumerable<string> issueKeys)
4248
{
43-
WorkLogType[] activities = Array.Empty<WorkLogType>();
49+
WorkLogType[] activities = await GetAvailableActivities(string.Empty);
4450

4551
Dictionary<string, WorkLogType[]> result = issueKeys
4652
.Select(issueKey => new ValueTuple<string, WorkLogType[]>(issueKey, activities))
@@ -51,7 +57,6 @@ public async Task<Dictionary<string, WorkLogType[]>> GetAvailableActivities(IEnu
5157

5258
return result;
5359
}
54-
#pragma warning restore
5560

5661
public async Task<WorkLog[]> GetIssueWorklogs(DateOnly from, DateOnly to, string issueKey)
5762
{
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace jwl.jira.api.rest.response;
2+
3+
// 2do!
4+
public class ICTimeActivityDefinition
5+
{
6+
public ICTimeActivityDefinition(int id, string name)
7+
{
8+
Id = id;
9+
Name = name;
10+
}
11+
12+
public int Id { get; set; }
13+
public string Name { get; set; }
14+
}

0 commit comments

Comments
 (0)