diff --git a/PlexRequests.UI/Content/issues.js b/PlexRequests.UI/Content/issues.js new file mode 100644 index 000000000..74d0afda3 --- /dev/null +++ b/PlexRequests.UI/Content/issues.js @@ -0,0 +1,227 @@ +Handlebars.registerHelper('if_eq', function (a, b, opts) { + if (a == b) + return !opts ? null : opts.fn(this); + else + return !opts ? null : opts.inverse(this); +}); + +var issueSource = $("#issue-template").html(); +var issueTemplate = Handlebars.compile(issueSource); + +var base = $('#baseUrl').text(); + + + +initLoad(); + + + +// Report Issue +$(document).on("click", ".dropdownIssue", function (e) { + var issue = $(this).attr("issue-select"); + var id = e.target.id; + // Other issue so the modal is opening + if (issue == 4) { + return; + } + e.preventDefault(); + + var $form = $('#report' + id); + var data = $form.serialize(); + data = data + "&issue=" + issue; + + $.ajax({ + type: $form.prop('method'), + url: $form.prop('action'), + data: data, + dataType: "json", + success: function (response) { + if (checkJsonResponse(response)) { + generateNotify("Success! Added Issue.", "success"); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); +}); + +// Modal click +$(".theSaveButton").click(function (e) { + var comment = $("#commentArea").val(); + e.preventDefault(); + + var $form = $("#commentForm"); + var data = $form.serialize(); + data = data + "&issue=" + 4 + "&comment=" + comment; + + $.ajax({ + type: $form.prop("method"), + url: $form.prop("action"), + data: data, + dataType: "json", + success: function (response) { + if (checkJsonResponse(response)) { + generateNotify("Success! Added Issue.", "success"); + $("#myModal").modal("hide"); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); +}); + +// Note Modal click +$(".theNoteSaveButton").click(function (e) { + var comment = $("#noteArea").val(); + e.preventDefault(); + + var $form = $("#noteForm"); + var data = $form.serialize(); + + + $.ajax({ + type: $form.prop("method"), + url: $form.prop("action"), + data: data, + dataType: "json", + success: function (response) { + if (checkJsonResponse(response)) { + generateNotify("Success! Added Note.", "success"); + $("#myModal").modal("hide"); + $('#adminNotesArea' + e.target.value).html("
Note from Admin: " + comment + "
"); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); +}); + +// Update the modal +$('#myModal').on('show.bs.modal', function (event) { + var button = $(event.relatedTarget); // Button that triggered the modal + var id = button.data('identifier'); // Extract info from data-* attributes + + var modal = $(this); + modal.find('.theSaveButton').val(id); // Add ID to the button + var requestField = modal.find('input'); + requestField.val(id); // Add ID to the hidden field +}); + +// Update the note modal +$('#noteModal').on('show.bs.modal', function (event) { + var button = $(event.relatedTarget); // Button that triggered the modal + var id = button.data('identifier'); // Extract info from data-* attributes + + var modal = $(this); + modal.find('.theNoteSaveButton').val(id); // Add ID to the button + var requestField = modal.find('.noteId'); + requestField.val(id); // Add ID to the hidden field +}); + +// Delete +$(document).on("click", ".delete", function (e) { + e.preventDefault(); + var buttonId = e.target.id; + var $form = $('#delete' + buttonId); + + $.ajax({ + type: $form.prop('method'), + url: $form.prop('action'), + data: $form.serialize(), + dataType: "json", + success: function (response) { + + if (checkJsonResponse(response)) { + generateNotify("Success! Request Deleted.", "success"); + + $("#" + buttonId + "Template").slideUp(); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); + +}); + +// Clear issues +$(document).on("click", ".clear", function (e) { + e.preventDefault(); + var buttonId = e.target.id; + var $form = $('#clear' + buttonId); + + $.ajax({ + type: $form.prop('method'), + url: $form.prop('action'), + data: $form.serialize(), + dataType: "json", + success: function (response) { + + if (checkJsonResponse(response)) { + generateNotify("Success! Issues Cleared.", "info"); + $('#issueArea' + buttonId).html("
Issue: None
"); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); + +}); + + +function initLoad() { + loadPendingIssues(); + +} + + +function loadPendingIssues() { + $issues = $('#pendingIssues'); + var url = createBaseUrl(base, "issues/pending"); + var linkUrl = createBaseUrl(base, "issues/"); + $.ajax({ + type: "get", + url: url, + dataType: "json", + success: function (response) { + if (response.length > 0) { + response.forEach(function(result) { + var context = buildIssueContext(result); + var html = issueTemplate(context); + $issues.append(html); + + $("#" +result.id + "link").attr("href", linkUrl + result.id); + }); + }; + }, + error: function (e) { + console.log(e); + generateNotify("Could not load Pending issues", "danger"); + } + }); + +} + + +// Builds the issue context. +function buildIssueContext(result) { + var context = { + id: result.id, + requestId: result.requestId, + type: result.type, + title: result.title, + count: result.count + }; + + return context; +} + diff --git a/PlexRequests.UI/Helpers/BaseUrlHelper.cs b/PlexRequests.UI/Helpers/BaseUrlHelper.cs index 331cf5e31..12b6fcca3 100644 --- a/PlexRequests.UI/Helpers/BaseUrlHelper.cs +++ b/PlexRequests.UI/Helpers/BaseUrlHelper.cs @@ -101,6 +101,18 @@ namespace PlexRequests.UI.Helpers sb.AppendLine($""); + return helper.Raw(sb.ToString()); + } + + public static IHtmlString LoadIssueAssets(this HtmlHelpers helper) + { + var sb = new StringBuilder(); + var assetLocation = GetBaseUrl(); + + var content = GetContentUrl(assetLocation); + + sb.AppendLine($""); + return helper.Raw(sb.ToString()); } diff --git a/PlexRequests.UI/Models/IssuesViewMOdel.cs b/PlexRequests.UI/Models/IssuesViewMOdel.cs new file mode 100644 index 000000000..e26eb26c3 --- /dev/null +++ b/PlexRequests.UI/Models/IssuesViewMOdel.cs @@ -0,0 +1,41 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: IssuesViewModel.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using PlexRequests.Store; + +namespace PlexRequests.UI.Models +{ + public class IssuesViewModel + { + public int Id { get; set; } + public int RequestId { get; set; } + public string Title { get; set; } + public int Count { get; set; } + public string Type { get; set; } + + } +} \ No newline at end of file diff --git a/PlexRequests.UI/Modules/IssuesModule.cs b/PlexRequests.UI/Modules/IssuesModule.cs index 6cca1c935..c872b2608 100644 --- a/PlexRequests.UI/Modules/IssuesModule.cs +++ b/PlexRequests.UI/Modules/IssuesModule.cs @@ -2,8 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; - +using System.Web.UI.WebControls; using Nancy; +using Nancy.Extensions; using Nancy.Responses.Negotiation; using Nancy.Security; @@ -14,6 +15,7 @@ using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Helpers; using PlexRequests.Store; +using PlexRequests.UI.Helpers; using PlexRequests.UI.Models; namespace PlexRequests.UI.Modules @@ -31,9 +33,9 @@ namespace PlexRequests.UI.Modules Post["/issue", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null); - Get["/inprogress", true] = async (x, ct) => await GetInProgressIssues(IssueStatus.InProgressIssue); - Get["/pending", true] = async (x, ct) => await GetInProgressIssues(IssueStatus.PendingIssue); - Get["/resolved", true] = async (x, ct) => await GetInProgressIssues(IssueStatus.ResolvedIssue); + Get["/inprogress", true] = async (x, ct) => await GetIssues(IssueStatus.InProgressIssue); + Get["/pending", true] = async (x, ct) => await GetIssues(IssueStatus.PendingIssue); + Get["/resolved", true] = async (x, ct) => await GetIssues(IssueStatus.ResolvedIssue); Post["/remove", true] = async (x, ct) => await RemoveIssue((int)Request.Form.issueId); @@ -51,11 +53,17 @@ namespace PlexRequests.UI.Modules return View["Index"]; } - private async Task GetInProgressIssues(IssueStatus status) + private async Task GetIssues(IssueStatus status) { var issues = await IssuesService.GetAllAsync(); - return Response.AsJson(issues.Where(x => x.IssueStatus == status)); + var issuesModels = issues as IssuesModel[] ?? issues.Where(x => x.IssueStatus == status).ToArray(); + var model = issuesModels.Select(i => new IssuesViewModel + { + Title = i.Title, Type = i.Type.ToString().CamelCaseToWords(), Count = i.Issues.Count, Id = i.Id, RequestId = i.RequestId + }).ToList(); + + return Response.AsJson(model); } public async Task IssueCount() diff --git a/PlexRequests.UI/PlexRequests.UI.csproj b/PlexRequests.UI/PlexRequests.UI.csproj index 5b2cdaa8b..a71061777 100644 --- a/PlexRequests.UI/PlexRequests.UI.csproj +++ b/PlexRequests.UI/PlexRequests.UI.csproj @@ -176,6 +176,7 @@ + @@ -242,6 +243,9 @@ + + PreserveNewest + PreserveNewest diff --git a/PlexRequests.UI/Views/Issues/Details.cshtml b/PlexRequests.UI/Views/Issues/Details.cshtml index b323e7495..f451f1ac2 100644 --- a/PlexRequests.UI/Views/Issues/Details.cshtml +++ b/PlexRequests.UI/Views/Issues/Details.cshtml @@ -11,5 +11,4 @@
User Reported: @issue.UserReported
User Note: @issue.UserNote
Admin Note: @issue.AdminNote
-
Status: @issue.IssueStatus
} \ No newline at end of file diff --git a/PlexRequests.UI/Views/Issues/Index.cshtml b/PlexRequests.UI/Views/Issues/Index.cshtml index 5f282702b..7621843c5 100644 --- a/PlexRequests.UI/Views/Issues/Index.cshtml +++ b/PlexRequests.UI/Views/Issues/Index.cshtml @@ -1 +1,42 @@ - \ No newline at end of file +@using PlexRequests.UI.Helpers +

Issues

+

Below you can see yours and all your current issues and their state.

+
+
+

Pending Issues


+
+ + + +@Html.LoadIssueAssets() \ No newline at end of file