Skip to content

Commit

Permalink
Bulk Create Responses (#150)
Browse files Browse the repository at this point in the history
* Bulk Create Responses

Rather than entering each response on a new page, allow for responses to be created in Excel and imported in bulk.

* Update with auth

* use validation
  • Loading branch information
tabascq authored Jan 14, 2019
1 parent 93212ce commit 7fbab26
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 0 deletions.
64 changes: 64 additions & 0 deletions ServerCore/Pages/Responses/CreateBulk.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
@page "/{eventId}/{eventRole}/Responses/CreateBulk/{puzzleId}"
@model ServerCore.Pages.Responses.CreateBulkModel

@{
ViewData["Title"] = "Bulk Create";
}

<h2>Bulk Create</h2>

<h4>Response</h4>
<hr />
<div class="row">
<div class="col-md-4">
<div>
<p>Intended usage: Enter data for each response in Excel, one line per response. Then copy each column into the correct box below and click Bulk Create.</p>
<br />
<p>IsSolution and Note can be blank when unused. IsSolution will be checked if you supply Y, Yes, T, or True (case insensitive).</p>
<br />
</div>
<form method="post">
<table>
<thead>
<tr>
<th>IsSolution</th>
<th>SubmittedText</th>
<th>ResponseText</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<textarea asp-for="IsSolution"></textarea>
<span asp-validation-for="IsSolution" class="text-danger"></span>
</td>
<td>
<textarea asp-for="SubmittedText"></textarea>
<span asp-validation-for="SubmittedText" class="text-danger"></span>
</td>
<td>
<textarea asp-for="ResponseText"></textarea>
<span asp-validation-for="ResponseText" class="text-danger"></span>
</td>
<td>
<textarea asp-for="Note"></textarea>
<span asp-validation-for="Note" class="text-danger"></span>
</td>
</tr>
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Bulk Create" class="btn btn-default" />
</div>
</form>
</div>
</div>

<div>
<a asp-page="Index" asp-route-puzzleid="@Model.PuzzleId">Back to Response List</a>
</div>

@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
108 changes: 108 additions & 0 deletions ServerCore/Pages/Responses/CreateBulk.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using ServerCore.DataModel;
using ServerCore.ModelBases;

namespace ServerCore.Pages.Responses
{
[Authorize(Policy = "IsEventAdminOrAuthorOfPuzzle")]
public class CreateBulkModel : EventSpecificPageModel
{
public CreateBulkModel(PuzzleServerContext serverContext, UserManager<IdentityUser> userManager) : base(serverContext, userManager)
{
}

[BindProperty]
public string IsSolution { get; set; }

[BindProperty]
public string SubmittedText { get; set; }

[BindProperty]
public string ResponseText { get; set; }

[BindProperty]
public string Note { get; set; }

public int PuzzleId { get; set; }

public IActionResult OnGet(int puzzleId)
{
PuzzleId = puzzleId;
return Page();
}

public async Task<IActionResult> OnPostAsync(int puzzleId)
{
if (!ModelState.IsValid)
{
return Page();
}

StringReader isSolutionReader = new StringReader(IsSolution ?? string.Empty);
StringReader submittedTextReader = new StringReader(SubmittedText ?? string.Empty);
StringReader responseTextReader = new StringReader(ResponseText ?? string.Empty);
StringReader noteReader = new StringReader(Note ?? string.Empty);

while (true)
{
string isSolution = isSolutionReader.ReadLine();
string submittedText = submittedTextReader.ReadLine();
string responseText = responseTextReader.ReadLine();
string note = noteReader.ReadLine();

// TODO probably clearer ways to validate but I honestly do not understand how validation works
if (submittedText == null)
{
if (responseText != null)
{
ModelState.AddModelError("ResponseText", "Unmatched Response without Submission");
}
if (isSolution != null)
{
ModelState.AddModelError("IsSolution", "Unmatched IsSolution without Submission");
}
if (note != null)
{
ModelState.AddModelError("Note", "Unmatched Note without Submission");
}

// we're done
break;
}

if (responseText == null)
{
ModelState.AddModelError("SubmittedText", "Unmatched Submission without Response");
break;
}

isSolution = isSolution == null ? string.Empty : isSolution.ToLower();

Response response = new Response()
{
PuzzleID = puzzleId,
SubmittedText = submittedText,
ResponseText = responseText,
Note = note,
IsSolution = isSolution == "y" || isSolution == "yes" || isSolution == "t" || isSolution == "true" || isSolution == "1"
};

_context.Responses.Add(response);
}

if (!ModelState.IsValid)
{
return Page();
}

await _context.SaveChangesAsync();

return RedirectToPage("./Index", new { puzzleid = puzzleId });
}
}
}
3 changes: 3 additions & 0 deletions ServerCore/Pages/Responses/Index.cshtml
Original file line number Diff line number Diff line change