Skip to content

Commit f7299b1

Browse files
fustomCopilot
andauthored
Add team iterations (#122)
* Add team iterations * Update CloneDevOpsTemplateTest/Services/TeamSettingsServiceTest.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent a079a28 commit f7299b1

13 files changed

Lines changed: 514 additions & 9 deletions

File tree

CloneDevOpsTemplate/Controllers/TeamSettingsController.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ public async Task<IActionResult> TeamFieldValues(Guid projectId, Guid teamId)
3939
return View(teamFieldValues);
4040
}
4141

42+
[HttpGet]
43+
public async Task<IActionResult> Iterations(Guid projectId, Guid teamId)
44+
{
45+
TeamIterations iterations = new();
46+
47+
if (!ModelState.IsValid)
48+
{
49+
return View(iterations.Value);
50+
}
51+
52+
iterations = await _teamSettingsService.GetIterations(projectId, teamId) ?? new();
53+
return View(iterations.Value);
54+
}
55+
4256
[HttpGet]
4357
public async Task<IActionResult> CloneTeamSettings()
4458
{
@@ -59,4 +73,24 @@ public async Task<IActionResult> CloneTeamSettings(Guid templateProjectId, Guid
5973

6074
return await CloneTeamSettings();
6175
}
76+
77+
[HttpGet]
78+
public async Task<IActionResult> CloneTeamIterations()
79+
{
80+
return await CloneTeamSettings();
81+
}
82+
83+
[HttpPost]
84+
public async Task<IActionResult> CloneTeamIterations(Guid templateProjectId, Guid projectId, Guid templateTeamId, Guid projectTeamId)
85+
{
86+
if (!ModelState.IsValid)
87+
{
88+
return await CloneTeamIterations();
89+
}
90+
91+
await _cloneManager.CloneTeamIterationsAsync(templateProjectId, projectId, templateTeamId, projectTeamId);
92+
ViewBag.SuccessMessage = "Success";
93+
94+
return await CloneTeamIterations();
95+
}
6296
}

CloneDevOpsTemplate/IServices/ITeamSettingsService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ public interface ITeamSettingsService
88
Task<HttpResponseMessage> UpdateTeamSettings(Guid projectId, Guid teamId, PatchTeamSettings teamSettings);
99
Task<TeamFieldValues?> GetTeamFieldValues(Guid projectId, Guid teamId);
1010
Task<HttpResponseMessage> UpdateTeamFieldValues(Guid projectId, Guid teamId, TeamFieldValues teamFieldValues);
11+
Task<TeamIterations?> GetIterations(Guid projectId, Guid teamId);
12+
Task<HttpResponseMessage> CreateIteration(Guid projectId, Guid teamId, Guid iterationId);
13+
Task<HttpResponseMessage> DeleteIteration(Guid projectId, Guid teamId, Guid iterationId);
1114
}

CloneDevOpsTemplate/Managers/CloneManager.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public async Task CloneTeamsAndSettingsAndBoardsAsync(Project templateProject, P
8686
foreach (var mappedTeam in mapTeams)
8787
{
8888
await CloneTeamSettingsAsync(templateProject.Id, project.Id, mappedTeam.Key, mappedTeam.Value);
89+
await CloneTeamIterationsAsync(templateProject.Id, project.Id, mappedTeam.Key, mappedTeam.Value);
8990
await CloneTeamFieldValuesAsync(templateProject, project, mappedTeam.Key, mappedTeam.Value);
9091
await CloneBoardsAsync(templateProject.Id, project.Id, mappedTeam.Key, mappedTeam.Value);
9192
}
@@ -112,7 +113,6 @@ await Parallel.ForEachAsync(repositories.Value, async (repository, ct) =>
112113
public async Task<Dictionary<Guid, Guid>> CloneTeamsAsync(Project templateProject, Project project)
113114
{
114115
Teams templateTeams = await _teamsService.GetTeamsAsync(templateProject.Id) ?? new();
115-
// TODO: TeamIterationMap
116116
return await _teamsService.CreateTeamFromTemplateAsync(project.Id, templateTeams.Value, templateProject.DefaultTeam.Id, project.DefaultTeam.Id);
117117
}
118118

@@ -171,4 +171,23 @@ await Task.WhenAll(
171171
_boardService.MoveCardStylesAsync(projectId, projectTeamId, templateProjectId, templateTeamId, projectBoards)
172172
);
173173
}
174+
175+
public async Task CloneTeamIterationsAsync(Guid templateProjectId, Guid projectId, Guid templateTeamId, Guid projectTeamId)
176+
{
177+
var oldIterations = await _teamSettingsService.GetIterations(projectId, projectTeamId) ?? new();
178+
foreach (var iteration in oldIterations.Value)
179+
{
180+
await _teamSettingsService.DeleteIteration(projectId, projectTeamId, iteration.Id);
181+
}
182+
183+
var iterations = await _teamSettingsService.GetIterations(templateProjectId, templateTeamId) ?? new();
184+
var iterationMap = await MapClassificationNodes(templateProjectId, projectId, TreeStructureGroup.Iterations);
185+
foreach (var iteration in iterations.Value)
186+
{
187+
if (iterationMap.TryGetValue(iteration.Id, out var mappedIterationId))
188+
{
189+
await _teamSettingsService.CreateIteration(projectId, projectTeamId, mappedIterationId);
190+
}
191+
}
192+
}
174193
}

CloneDevOpsTemplate/Managers/ICloneManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ public interface ICloneManager
1414
Task<Dictionary<Guid, Guid>> CloneTeamsAsync(Guid templateProjectId, Guid projectId);
1515
Task CloneTeamsAndSettingsAndBoardsAsync(Project templateProject, Project project);
1616
Task CloneTeamSettingsAsync(Guid templateProjectId, Guid projectId, Guid templateTeamId, Guid projectTeamId);
17+
Task CloneTeamIterationsAsync(Guid templateProjectId, Guid projectId, Guid templateTeamId, Guid projectTeamId);
1718
}

CloneDevOpsTemplate/Models/TeamSettings.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ public class TeamIterationSettings
6363

6464
public class TeamIterationAttributes
6565
{
66-
public DateTime FinishDate { set; get; }
67-
public DateTime StartDate { set; get; }
66+
public DateTime? FinishDate { set; get; }
67+
public DateTime? StartDate { set; get; }
6868
public TimeFrame TimeFrame { set; get; }
6969
}
7070

@@ -86,4 +86,10 @@ public class Values
8686
{
8787
public string Value { get; set; } = string.Empty;
8888
public bool IncludeChildren { get; set; }
89-
}
89+
}
90+
91+
public class TeamIterations
92+
{
93+
public int Count { get; set; }
94+
public TeamIterationSettings[] Value { get; set; } = [];
95+
}

CloneDevOpsTemplate/Services/TeamSettingsService.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,18 @@ public Task<HttpResponseMessage> UpdateTeamFieldValues(Guid projectId, Guid team
2727
{
2828
return _client.PatchAsJsonAsync($"{projectId}/{teamId}/_apis/work/teamsettings/teamfieldvalues?api-version=7.1", teamFieldValues);
2929
}
30+
31+
public Task<TeamIterations?> GetIterations(Guid projectId, Guid teamId)
32+
{
33+
return _client.GetFromJsonAsync<TeamIterations>($"{projectId}/{teamId}/_apis/work/teamsettings/iterations");
34+
}
35+
36+
public Task<HttpResponseMessage> CreateIteration(Guid projectId, Guid teamId, Guid iterationId)
37+
{
38+
return _client.PostAsJsonAsync($"{projectId}/{teamId}/_apis/work/teamsettings/iterations?api-version=7.1", new { id = iterationId });
39+
}
40+
public Task<HttpResponseMessage> DeleteIteration(Guid projectId, Guid teamId, Guid iterationId)
41+
{
42+
return _client.DeleteAsync($"{projectId}/{teamId}/_apis/work/teamsettings/iterations/{iterationId}?api-version=7.1");
43+
}
3044
}

CloneDevOpsTemplate/Views/Shared/_Header.cshtml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
<a class="dropdown-item" asp-controller="Team" asp-action="CloneTeamFieldValues">Team
5252
Field Values</a>
5353
</li>
54+
<li>
55+
<a class="dropdown-item" asp-controller="TeamSettings"
56+
asp-action="CloneTeamIterations">Team Iterations</a>
57+
</li>
5458
<li>
5559
<a class="dropdown-item" asp-controller="Boards" asp-action="CloneBoards">Boards</a>
5660
</li>

CloneDevOpsTemplate/Views/Team/Team.cshtml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
<tr>
2424
<td colspan="2">@Html.ActionLink("Team field values", "TeamFieldValues", "TeamSettings", new { projectId = Model.ProjectId, teamId = Model.Id })</td>
2525
</tr>
26+
<tr>
27+
<td colspan="2">@Html.ActionLink("Team iterations", "Iterations", "TeamSettings", new { projectId = Model.ProjectId, teamId = Model.Id })</td>
28+
</tr>
2629
<tr>
2730
<td colspan="2">@Html.ActionLink("Boards", "Boards", "Boards", new { projectId = Model.ProjectId, teamId = Model.Id })</td>
2831
</tr>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@model Team[]
2+
@{
3+
ViewData["Title"] = "Clone team iterations";
4+
}
5+
6+
<h1>Clone team iterations</h1>
7+
8+
@{
9+
await Html.RenderPartialAsync("_CloneByTeam", Tuple.Create(Model, "TeamSettings", "CloneTeamIterations"));
10+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@model TeamIterationSettings[]
2+
@{
3+
ViewData["Title"] = "Iterations";
4+
}
5+
6+
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
7+
8+
<h1>Iterations</h1>
9+
10+
<table class="table table-striped">
11+
<th class="table-primary">Iteration</th>
12+
<th class="table-primary">Start Date</th>
13+
<th class="table-primary">End Date</th>
14+
@foreach (var iteration in Model)
15+
{
16+
<tr>
17+
<td>@iteration.Name</td>
18+
<td>@iteration.Attributes.StartDate</td>
19+
<td>@iteration.Attributes.FinishDate</td>
20+
</tr>
21+
}
22+
</table>

0 commit comments

Comments
 (0)