Skip to content

Commit 7c673e9

Browse files
added endpoints for moving application instances (#41)
1 parent 1d747d5 commit 7c673e9

File tree

2 files changed

+138
-10
lines changed

2 files changed

+138
-10
lines changed

Player.Api/Controllers/ApplicationController.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ public async Task<IActionResult> DeleteApplication(Guid id, CancellationToken ct
252252
[SwaggerOperation(OperationId = "getTeamApplicationInstances")]
253253
public async Task<IActionResult> GetInstancesByTeam(Guid id, CancellationToken ct)
254254
{
255-
var list = await _applicationService.GetInstancesByTeamAsync(id, ct);
255+
var list = await _applicationService.GetInstancesByTeamAsync(id, skipVerification: false, ct);
256256
return Ok(list);
257257
}
258258

@@ -339,6 +339,44 @@ public async Task<IActionResult> DeleteApplicationInstance(Guid id, Cancellation
339339
return NoContent();
340340
}
341341

342+
/// <summary>
343+
/// Moves an Application Instance up
344+
/// </summary>
345+
/// <remarks>
346+
/// Moves an Application Instance up one spot in the list
347+
/// <para />
348+
/// Accessible only to a SuperUser or a User on an Admin Team in the Application Instances's Team's View
349+
/// </remarks>
350+
/// <param name="id">The id of the Application Instance</param>
351+
/// <param name="ct"></param>
352+
[HttpPost("application-instances/{id}/move-up")]
353+
[ProducesResponseType(typeof(IEnumerable<ApplicationInstance>), (int)HttpStatusCode.OK)]
354+
[SwaggerOperation(OperationId = "moveUpApplicationInstance")]
355+
public async Task<IActionResult> MoveUpApplicationInstance([FromRoute] Guid id, CancellationToken ct)
356+
{
357+
var updatedInstances = await _applicationService.MoveUpInstanceAsync(id, ct);
358+
return Ok(updatedInstances);
359+
}
360+
361+
/// <summary>
362+
/// Moves an Application Instance down
363+
/// </summary>
364+
/// <remarks>
365+
/// Moves an Application Instance down one spot in the list
366+
/// <para />
367+
/// Accessible only to a SuperUser or a User on an Admin Team in the Application Instances's Team's View
368+
/// </remarks>
369+
/// <param name="id">The id of the Application Instance</param>
370+
/// <param name="ct"></param>
371+
[HttpPost("application-instances/{id}/move-down")]
372+
[ProducesResponseType(typeof(IEnumerable<ApplicationInstance>), (int)HttpStatusCode.OK)]
373+
[SwaggerOperation(OperationId = "moveDownApplicationInstance")]
374+
public async Task<IActionResult> MoveDownApplicationInstance([FromRoute] Guid id, CancellationToken ct)
375+
{
376+
var updatedInstances = await _applicationService.MoveDownInstanceAsync(id, ct);
377+
return Ok(updatedInstances);
378+
}
379+
342380
#endregion
343381
}
344382
}

Player.Api/Services/ApplicationService.cs

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ public interface IApplicationService
3737
Task<bool> DeleteApplicationAsync(Guid id, CancellationToken ct);
3838

3939
// Application Instances
40-
Task<IEnumerable<ViewModels.ApplicationInstance>> GetInstancesByTeamAsync(Guid teamId, CancellationToken ct);
40+
Task<IEnumerable<ViewModels.ApplicationInstance>> GetInstancesByTeamAsync(Guid teamId, bool skipVerification, CancellationToken ct);
4141
Task<ViewModels.ApplicationInstance> GetInstanceAsync(Guid id, CancellationToken ct);
4242
Task<ViewModels.ApplicationInstance> CreateInstanceAsync(Guid teamId, ViewModels.ApplicationInstanceForm instance, CancellationToken ct);
4343
Task<ViewModels.ApplicationInstance> UpdateInstanceAsync(Guid id, ViewModels.ApplicationInstanceForm instance, CancellationToken ct);
44+
Task<IEnumerable<ViewModels.ApplicationInstance>> MoveUpInstanceAsync(Guid id, CancellationToken ct);
45+
Task<IEnumerable<ViewModels.ApplicationInstance>> MoveDownInstanceAsync(Guid id, CancellationToken ct);
4446
Task<bool> DeleteInstanceAsync(Guid id, CancellationToken ct);
4547
}
4648

@@ -225,24 +227,27 @@ public async Task<bool> DeleteApplicationAsync(Guid id, CancellationToken ct)
225227

226228
#region Application Instances
227229

228-
public async Task<IEnumerable<ViewModels.ApplicationInstance>> GetInstancesByTeamAsync(Guid teamId, CancellationToken ct)
230+
public async Task<IEnumerable<ViewModels.ApplicationInstance>> GetInstancesByTeamAsync(Guid teamId, bool skipVerification, CancellationToken ct)
229231
{
230-
var team = await _context.Teams
232+
if (!skipVerification)
233+
{
234+
var team = await _context.Teams
231235
.Where(e => e.Id == teamId)
232236
.SingleOrDefaultAsync(ct);
233237

238+
if (team == null)
239+
throw new EntityNotFoundException<Team>();
240+
241+
if (!(await _authorizationService.AuthorizeAsync(_user, null, new TeamAccessRequirement(team.ViewId, teamId))).Succeeded)
242+
throw new ForbiddenException();
243+
}
244+
234245
var instances = await _context.ApplicationInstances
235246
.Where(i => i.TeamId == teamId)
236247
.OrderBy(a => a.DisplayOrder)
237248
.ProjectTo<ViewModels.ApplicationInstance>(_mapper.ConfigurationProvider)
238249
.ToArrayAsync(ct);
239250

240-
if (team == null)
241-
throw new EntityNotFoundException<Team>();
242-
243-
if (!(await _authorizationService.AuthorizeAsync(_user, null, new TeamAccessRequirement(team.ViewId, teamId))).Succeeded)
244-
throw new ForbiddenException();
245-
246251
return instances;
247252
}
248253

@@ -322,6 +327,91 @@ public async Task<bool> DeleteInstanceAsync(Guid id, CancellationToken ct)
322327
return true;
323328
}
324329

330+
public async Task<IEnumerable<ViewModels.ApplicationInstance>> MoveUpInstanceAsync(Guid id, CancellationToken ct)
331+
{
332+
return await this.MoveInstanceAsync(id, Direction.Up, ct);
333+
}
334+
335+
public async Task<IEnumerable<ViewModels.ApplicationInstance>> MoveDownInstanceAsync(Guid id, CancellationToken ct)
336+
{
337+
return await this.MoveInstanceAsync(id, Direction.Down, ct);
338+
}
339+
340+
private enum Direction
341+
{
342+
Up,
343+
Down
344+
}
345+
346+
private async Task<IEnumerable<ViewModels.ApplicationInstance>> MoveInstanceAsync(Guid id, Direction direction, CancellationToken ct)
347+
{
348+
var instanceToUpdate = await _context.ApplicationInstances
349+
.Include(x => x.Team)
350+
.SingleOrDefaultAsync(x => x.Id == id, ct);
351+
352+
if (instanceToUpdate == null)
353+
throw new EntityNotFoundException<ApplicationInstance>();
354+
355+
if (!(await _authorizationService.AuthorizeAsync(_user, null, new ViewAdminRequirement(instanceToUpdate.Team.ViewId))).Succeeded)
356+
throw new ForbiddenException();
357+
358+
var teamInstances = await _context.ApplicationInstances
359+
.Where(x => x.TeamId == instanceToUpdate.TeamId)
360+
.OrderBy(x => x.DisplayOrder)
361+
.ToArrayAsync(ct);
362+
363+
if (direction == Direction.Up)
364+
{
365+
for (int i = 0; i < teamInstances.Length; i++)
366+
{
367+
var teamInstance = teamInstances[i];
368+
369+
if (teamInstance.Id == id)
370+
{
371+
teamInstance.DisplayOrder = i - 1;
372+
373+
var previous = teamInstances.ElementAtOrDefault(i - 1);
374+
375+
if (previous != null)
376+
{
377+
previous.DisplayOrder = previous.DisplayOrder + 1;
378+
}
379+
}
380+
else
381+
{
382+
teamInstance.DisplayOrder = i;
383+
}
384+
}
385+
}
386+
else if (direction == Direction.Down)
387+
{
388+
for (int i = teamInstances.Length - 1; i >= 0; i--)
389+
{
390+
var teamInstance = teamInstances[i];
391+
392+
if (teamInstance.Id == id)
393+
{
394+
teamInstance.DisplayOrder = i + 1;
395+
396+
var previous = teamInstances.ElementAtOrDefault(i + 1);
397+
398+
if (previous != null)
399+
{
400+
previous.DisplayOrder = previous.DisplayOrder - 1;
401+
}
402+
}
403+
else
404+
{
405+
teamInstance.DisplayOrder = i;
406+
}
407+
}
408+
}
409+
410+
await _context.SaveChangesAsync(ct);
411+
412+
return await this.GetInstancesByTeamAsync(instanceToUpdate.TeamId, skipVerification: true, ct);
413+
}
414+
325415
#endregion
326416
}
327417
}

0 commit comments

Comments
 (0)