From 5fcfdadf8641188014de760e40e76eb5d496cc17 Mon Sep 17 00:00:00 2001 From: SuperPotatoMen Date: Thu, 12 Jan 2017 23:23:49 +0100 Subject: [PATCH 1/4] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2d8951efc..636de15ae 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ We integrate with the following applications: * Sonarr * SickRage * CouchPotato +* Watcher * Headphones ### Notifications From 0659697758696bba9443207869534e95d7a3a292 Mon Sep 17 00:00:00 2001 From: SuperPotatoMen Date: Thu, 12 Jan 2017 23:26:35 +0100 Subject: [PATCH 2/4] Update README.md --- README.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 636de15ae..5a65a184e 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,21 @@ ____ [![Stories in Progress](https://badge.waffle.io/tidusjar/Ombi.svg?label=in progress&title=In Progress)](http://waffle.io/tidusjar/Ombi) +# Feature Requests +Feature requests are handled on FeatHub. + +Search the existing requests to see if your suggestion has already been submitted. +(If a similar request exists, give it a thumbs up (+1), or add additional comments to the request) + +#### [![Feature Requests](https://cloud.githubusercontent.com/assets/390379/10127973/045b3a96-6560-11e5-9b20-31a2032956b2.png)](http://feathub.com/tidusjar/Ombi) + # Features Here some of the features Ombi has: * All your users to Request Movies, TV Shows (Whole series, whole seaons or even single episodes!) and Albums * Easily manage your requests +* User mangement system (supports plex.tv accounts and local accounts) +* Sending newsletters +* Fault Queue for requests (Buffer requests if Sonar/Couchpotato/SickRage is offline) * Allow your users to report issues and manage them seperatly * A landing page that will give you the availability of your Plex server and also add custom notification text to inform your users of downtime. * Allow your users to get notifications! @@ -23,13 +34,13 @@ Here some of the features Ombi has: * It automatically update the status of requests when they are available on Plex * Slick, responsive and mobile friendly UI + ### Integration We integrate with the following applications: -* Plex (Obviously!) +* Plex server 1.2 (and higher) * Sonarr * SickRage * CouchPotato -* Watcher * Headphones ### Notifications @@ -61,16 +72,13 @@ Looking for a Docker Image? Well [rogueosb](https://github.com/rogueosb/) has cr We are looking for any contributions to the project! Just pick up a task, if you have any questions ask and i'll get straight on it! -Please feel free to submit a pull request! +Please feed free to submit a pull request! # Donation If you feel like donating you can [here!](https://paypal.me/PlexRequestsNet) ### A massive thanks to everyone for all their help! -## [Feathub](http://feathub.com/tidusjar/Ombi) -[![Feature Requests](http://feathub.com/tidusjar/Ombi?format=svg)](http://feathub.com/tidusjar/Ombi) - - ## Stats -[![Throughput Graph](https://graphs.waffle.io/tidusjar/Ombi/throughput.svg)](https://waffle.io/tidusjar/Ombi/metrics/throughput) +[![Throughput Graph](https://graphs.waffle.io/tidusjar/PlexRequests.Net/throughput.svg)](https://waffle.io/tidusjar/PlexRequests.Net/metrics/throughput) + From bef6e036f75a772c6a0c4470f22c9af7aeb164d6 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Fri, 13 Jan 2017 09:02:53 +0000 Subject: [PATCH 3/4] Added the settings for #925 but need to apply the settings to the UI --- .../SettingModels/CustomizationSettings.cs | 18 ++++ Ombi.Helpers/EnumHelper.cs | 13 +++ Ombi.UI/Content/requests.js | 38 ++++---- .../Models/Admin/CustomizationViewModel.cs | 91 +++++++++++++++++++ Ombi.UI/Models/UI/Dropdown.cs | 35 +++++++ Ombi.UI/Modules/Admin/CustomizationModule.cs | 68 +++++++++++++- Ombi.UI/Modules/RequestsModule.cs | 21 ++++- Ombi.UI/Ombi.UI.csproj | 3 + .../Views/Customization/Customization.cshtml | 82 +++++++++++++++-- Ombi.UI/Views/Shared/Partial/_Navbar.cshtml | 2 +- 10 files changed, 335 insertions(+), 36 deletions(-) create mode 100644 Ombi.UI/Models/Admin/CustomizationViewModel.cs create mode 100644 Ombi.UI/Models/UI/Dropdown.cs diff --git a/Ombi.Core/SettingModels/CustomizationSettings.cs b/Ombi.Core/SettingModels/CustomizationSettings.cs index 6225861ad..2fa664f35 100644 --- a/Ombi.Core/SettingModels/CustomizationSettings.cs +++ b/Ombi.Core/SettingModels/CustomizationSettings.cs @@ -35,5 +35,23 @@ namespace Ombi.Core.SettingModels /// The CSS name of the theme we want /// public string ThemeName { get; set; } + + /// + /// Admin Only. + /// + /// + /// The default filter. + /// + public int DefaultFilter { get; set; } + /// + /// Admin only. + /// + /// + /// The default sort. + /// + public int DefaultSort { get; set; } + + public int DefaultLang { get; set; } + } } \ No newline at end of file diff --git a/Ombi.Helpers/EnumHelper.cs b/Ombi.Helpers/EnumHelper.cs index 316de8ec7..db1ced9da 100644 --- a/Ombi.Helpers/EnumHelper.cs +++ b/Ombi.Helpers/EnumHelper.cs @@ -82,6 +82,19 @@ namespace Ombi.Helpers if (descriptionAttributes == null) return string.Empty; return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Name : value.ToString(); } + public static string GetDisplayDescription(T value) + { + var fieldInfo = value.GetType().GetField(value.ToString()); + + var descriptionAttributes = fieldInfo.GetCustomAttributes( + typeof(DisplayAttribute), false) as DisplayAttribute[]; + + if (descriptionAttributes[0].ResourceType != null) + return LookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Description); + + if (descriptionAttributes == null) return string.Empty; + return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Description : value.ToString(); + } public static T GetValueFromName(string name) { diff --git a/Ombi.UI/Content/requests.js b/Ombi.UI/Content/requests.js index 7af2631ed..31a5a3761 100644 --- a/Ombi.UI/Content/requests.js +++ b/Ombi.UI/Content/requests.js @@ -17,8 +17,26 @@ var tvLoaded = false; var albumLoaded = false; var isAdmin = $('#isAdmin').text(); + + var defaultFiler = isAdmin == 'True' ? '.approved-fase' : 'all'; +var url = createBaseUrl(base, '/requests/UpdateFilters'); +$.ajax({ + type: 'GET', + url: url, + dataType: "json", + success: function (response) { + + mixItUpDefault.load.filter = response.defaultFilter; + mixItUpDefault.load.sort = response.defaultSort; + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong saving your filter!", "danger"); + } +}); + var mixItUpDefault = { animation: { enable: true }, load: { @@ -30,26 +48,6 @@ var mixItUpDefault = { }, callbacks: { onMixStart: function (state, futureState) { - //futureState.activeSort // sort - //futureState.activeFilter // next filter - - // The below is TODO for saving the users filter and sort order - //var url = createBaseUrl(base, '/requests/UpdateFilters'); - //$.ajax({ - // type: 'post', - // url: url, - // data: {sort:futureState.activeSort, filter:futureState.activeFilte}, - // dataType: "json", - // success: function (response) { - // console.log("saved filter and sort order"); - // }, - // error: function (e) { - // console.log(e); - // generateNotify("Something went wrong saving your filter!", "danger"); - // } - //}); - - $('.mix', this).removeAttr('data-bound').removeData('bound'); // fix for animation issues in other tabs } } diff --git a/Ombi.UI/Models/Admin/CustomizationViewModel.cs b/Ombi.UI/Models/Admin/CustomizationViewModel.cs new file mode 100644 index 000000000..1c6082af3 --- /dev/null +++ b/Ombi.UI/Models/Admin/CustomizationViewModel.cs @@ -0,0 +1,91 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: CustomizationViewModel.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 System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Ombi.Core.SettingModels; +using Ombi.UI.Models.UI; + +namespace Ombi.UI.Models.Admin +{ + public class CustomizationViewModel + { + public CustomizationSettings Settings { get; set; } + public List> LanguageDropdown { get; set; } = new List>(); + public List> FilterOptions { get; set; } = new List>(); + public List> SortOptions { get; set; } = new List>(); + } + + public enum FilterOptions + { + [Display(Name = ".available-true", Description = "Available")] + Available, + [Display(Name = ".available-false", Description = "Not Available")] + NotAvailable, + [Display(Name = ".released-true", Description = "Released")] + Released, + [Display(Name = ".released-false", Description = "Not Released")] + NotReleased + } + + public enum SortOptions + { + [Display(Name = "requestorder:desc", Description = "Latest Requests")] + LatestRequests, + [Display(Name = "requestorder:asc", Description = "Oldest Requests")] + OldestRequests, + [Display(Name = "releaseorder:desc", Description = "Latest Releases")] + LatestRelease, + [Display(Name = "releaseorder:asc", Description = "Oldest Releases")] + OldestRelease + } + + public enum Languages + { + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_English")] + en, + + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_French")] + fr, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Dutch")] + nl, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Spanish")] + es, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_German")] + de, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Danish")] + da, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Portuguese")] + pt, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Swedish")] + sv, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Italian")] + it + } +} \ No newline at end of file diff --git a/Ombi.UI/Models/UI/Dropdown.cs b/Ombi.UI/Models/UI/Dropdown.cs new file mode 100644 index 000000000..834a7cf61 --- /dev/null +++ b/Ombi.UI/Models/UI/Dropdown.cs @@ -0,0 +1,35 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: Dropdown.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 +namespace Ombi.UI.Models.UI +{ + public class Dropdown + { + public bool Selected { get; set; } + public string Name { get; set; } + public T Value { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.UI/Modules/Admin/CustomizationModule.cs b/Ombi.UI/Modules/Admin/CustomizationModule.cs index a368e66f4..d34e41ee2 100644 --- a/Ombi.UI/Modules/Admin/CustomizationModule.cs +++ b/Ombi.UI/Modules/Admin/CustomizationModule.cs @@ -1,4 +1,5 @@ #region Copyright + // /************************************************************************ // Copyright (c) 2016 Jamie Rees // File: CustomizationModule.cs @@ -23,43 +24,94 @@ // 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 System; +using System.Collections.Generic; using System.Threading.Tasks; using Nancy; using Nancy.ModelBinding; using Nancy.Responses.Negotiation; using Ombi.Core; using Ombi.Core.SettingModels; +using Ombi.Helpers; using Ombi.Helpers.Permissions; using Ombi.UI.Models; +using Ombi.UI.Models.Admin; +using Ombi.UI.Models.UI; +using TMDbLib.Utilities; using ISecurityExtensions = Ombi.Core.ISecurityExtensions; namespace Ombi.UI.Modules.Admin { public class CustomizationModule : BaseModule { - public CustomizationModule(ISettingsService settingsService, ISettingsService cust, ISecurityExtensions security) : base("admin", settingsService, security) + public CustomizationModule(ISettingsService settingsService, + ISettingsService cust, ISecurityExtensions security) + : base("admin", settingsService, security) { Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx); Settings = cust; - Get["/customization", true] = async (x,ct) => await Index(); - Post["/customization", true] = async (x,ct) => await Save(); + Get["/customization", true] = async (x, ct) => await Index(); + Post["/customization", true] = async (x, ct) => await Save(); } - + private ISettingsService Settings { get; } private async Task Index() { var model = await Settings.GetSettingsAsync(); - return View["customization", model]; + var viewModel = new CustomizationViewModel + { + Settings = model, + SortOptions = new List>() + }; + + + + + foreach (var value in EnumHelper.GetValues(SortOptions.LatestRelease)) + { + viewModel.SortOptions.Add(new Dropdown + { + Value = value, + Name = EnumHelper.GetDisplayDescription(value), + Selected = model.DefaultSort == (int) value + }); + } + + foreach (var value in EnumHelper.GetValues(FilterOptions.Available)) + { + viewModel.FilterOptions.Add(new Dropdown + { + Value = value, + Name = EnumHelper.GetDisplayDescription(value), + Selected = model.DefaultFilter == (int) value + }); + } + + foreach (var value in EnumHelper.GetValues(Languages.en)) + { + viewModel.LanguageDropdown.Add(new Dropdown + { + Value = value, + Name = EnumHelper.GetDisplayValue(value), + Selected = model.DefaultLang == (int) value + }); + } + + return View["customization", viewModel]; } private async Task Save() { + try + { + var model = this.Bind(); var result = await Settings.SaveSettingsAsync(model); @@ -67,6 +119,12 @@ namespace Ombi.UI.Modules.Admin return Response.AsJson(result ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "We could not save to the database, please try again" }); + } + catch (Exception e) + { + + throw; + } } } } \ No newline at end of file diff --git a/Ombi.UI/Modules/RequestsModule.cs b/Ombi.UI/Modules/RequestsModule.cs index e304120e5..5d9d8596f 100644 --- a/Ombi.UI/Modules/RequestsModule.cs +++ b/Ombi.UI/Modules/RequestsModule.cs @@ -43,6 +43,7 @@ using Ombi.Services.Interfaces; using Ombi.Services.Notification; using Ombi.Store; using Ombi.UI.Models; +using Ombi.UI.Models.Admin; using Action = Ombi.Helpers.Analytics.Action; using ISecurityExtensions = Ombi.Core.ISecurityExtensions; @@ -64,7 +65,8 @@ namespace Ombi.UI.Modules ICacheProvider cache, IAnalytics an, INotificationEngine engine, - ISecurityExtensions security) : base("requests", prSettings, security) + ISecurityExtensions security, + ISettingsService customSettings) : base("requests", prSettings, security) { Service = service; PrSettings = prSettings; @@ -79,6 +81,7 @@ namespace Ombi.UI.Modules Cache = cache; Analytics = an; NotificationEngine = engine; + CustomizationSettings = customSettings; Get["/", true] = async (x, ct) => await LoadRequests(); Get["/movies", true] = async (x, ct) => await GetMovies(); @@ -92,7 +95,7 @@ namespace Ombi.UI.Modules Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); - Post["/UpdateFilters", true] = async (x, ct) => await UpdateFilters(); + Get["/UpdateFilters", true] = async (x, ct) => await GetFilterAndSortSettings(); } private static Logger Log = LogManager.GetCurrentClassLogger(); @@ -104,6 +107,7 @@ namespace Ombi.UI.Modules private ISettingsService SonarrSettings { get; } private ISettingsService SickRageSettings { get; } private ISettingsService CpSettings { get; } + private ISettingsService CustomizationSettings { get; } private ISonarrApi SonarrApi { get; } private ISickRageApi SickRageApi { get; } private ICouchPotatoApi CpApi { get; } @@ -408,11 +412,20 @@ namespace Ombi.UI.Modules : new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" }); } - private async Task UpdateFilters() + private async Task GetFilterAndSortSettings() { + var s = await CustomizationSettings.GetSettingsAsync(); + var sortVal = EnumHelper.GetDisplayValue((SortOptions)s.DefaultSort); + var filterVal = EnumHelper.GetDisplayValue((FilterOptions)s.DefaultFilter); - return Response.AsJson(""); + var vm = new + { + DefaultSort = sortVal, + DefaultFilter = filterVal + }; + + return Response.AsJson(vm); } } } diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index 74904233c..0a151d769 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -118,6 +118,7 @@ True + @@ -233,6 +234,7 @@ + @@ -247,6 +249,7 @@ + diff --git a/Ombi.UI/Views/Customization/Customization.cshtml b/Ombi.UI/Views/Customization/Customization.cshtml index 112fb6e44..ff2e7a296 100644 --- a/Ombi.UI/Views/Customization/Customization.cshtml +++ b/Ombi.UI/Views/Customization/Customization.cshtml @@ -1,14 +1,14 @@ @using Ombi.UI.Helpers -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @Html.Partial("Shared/Partial/_Sidebar") @{ var plexTheme = string.Empty; var originalTheme = string.Empty; - if (!string.IsNullOrEmpty(Model.ThemeName)) + if (!string.IsNullOrEmpty(Model.Settings.ThemeName)) { - plexTheme = Model.ThemeName.Equals(Themes.PlexTheme) ? "selected=\"selected\"" : string.Empty; - originalTheme = Model.ThemeName.Equals(Themes.OriginalTheme) ? "selected=\"selected\"" : string.Empty; + plexTheme = Model.Settings.ThemeName.Equals(Themes.PlexTheme) ? "selected=\"selected\"" : string.Empty; + originalTheme = Model.Settings.ThemeName.Equals(Themes.OriginalTheme) ? "selected=\"selected\"" : string.Empty; } else { @@ -26,7 +26,7 @@
- +
@@ -39,6 +39,69 @@ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
@@ -60,10 +123,17 @@ e.preventDefault(); var theme = $("#themes option:selected").val(); + var lang = $('#langSelect option:selected').val(); + var sort = $('#sortSelect option:selected').val(); + var filter = $('#filterSelect option:selected').val(); var $form = $("#mainForm"); var data = $form.serialize(); - data = data + "&themeName=" + theme; + data = data + + "&themeName=" + theme + + "&DefaultLang=" + lang + + "&DefaultSort=" + sort + + "&DefaultFilter=" + filter; $.ajax({ type: $form.prop("method"), diff --git a/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml b/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml index 9d3e24893..f801cc9a4 100644 --- a/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml +++ b/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml @@ -1,4 +1,4 @@ -ab@using Nancy.Security +@using Nancy.Security @using Nancy.Session @using Nancy; @using Ombi.Helpers From 39d77cdb19466f15bba0db2635d3991c0f328c92 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Fri, 13 Jan 2017 15:18:32 +0000 Subject: [PATCH 4/4] Finished #925 --- Ombi.UI/Content/requests.js | 51 +++++--- .../Models/Admin/CustomizationViewModel.cs | 10 +- .../Models/Requests/RequestsIndexViewModel.cs | 37 ++++++ Ombi.UI/Modules/RequestsModule.cs | 9 +- Ombi.UI/Ombi.UI.csproj | 1 + Ombi.UI/Views/Requests/Index.cshtml | 115 +++++++++--------- 6 files changed, 141 insertions(+), 82 deletions(-) create mode 100644 Ombi.UI/Models/Requests/RequestsIndexViewModel.cs diff --git a/Ombi.UI/Content/requests.js b/Ombi.UI/Content/requests.js index 31a5a3761..7928f39aa 100644 --- a/Ombi.UI/Content/requests.js +++ b/Ombi.UI/Content/requests.js @@ -16,32 +16,44 @@ var base = $('#baseUrl').text(); var tvLoaded = false; var albumLoaded = false; -var isAdmin = $('#isAdmin').text(); +var isAdmin = $('#isAdmin').text() === "True"; +var adminFilter = $('#adminFilter').text(); +var adminFilterText = $('#adminFilterText').text(); +var adminSort = $('#adminSort').text(); +var adminSortText = $('#adminSortText').text(); -var defaultFiler = isAdmin == 'True' ? '.approved-fase' : 'all'; +var defaultFilterText = $('#defaultFilterText').text(); +var defaultSortText = $('#defaultSortText').text(); -var url = createBaseUrl(base, '/requests/UpdateFilters'); -$.ajax({ - type: 'GET', - url: url, - dataType: "json", - success: function (response) { - mixItUpDefault.load.filter = response.defaultFilter; - mixItUpDefault.load.sort = response.defaultSort; - }, - error: function (e) { - console.log(e); - generateNotify("Something went wrong saving your filter!", "danger"); - } -}); +$("#filterText").text(isAdmin ? adminFilterText : defaultFilterText); +$("#sortText").text(isAdmin ? adminSortText : defaultSortText); + +// Loop through all the filters to set the correct one to checked +selectCheckboxes('.filter', isAdmin ? adminFilterText : defaultFilterText); +selectCheckboxes('.sort', isAdmin ? adminSortText : defaultSortText); + + +function selectCheckboxes(className, text) { + $(className).each(function (i, obj) { + + var $element = $(obj.children[0]); + if (obj.text === " " + text) { + $element.removeClass('fa-square-o').addClass('fa-check-square'); + } else { + if ($element.hasClass('fa-check-square')) { + $element.removeClass('fa-check-square').addClass('fa-square-o'); + } + } + }); +} var mixItUpDefault = { animation: { enable: true }, load: { - filter: defaultFiler, - sort: 'requestorder:desc' + filter: isAdmin ? adminFilter : 'all', + sort: isAdmin ? adminSort : 'requestorder:desc' }, layout: { display: 'block' @@ -293,6 +305,9 @@ $('.sort', '.dropdown-menu').click(function (e) { var $this = $(this); $('.fa-check-square', $this.parents('.dropdown-menu:first')).removeClass('fa-check-square').addClass('fa-square-o'); $this.children('.fa').first().removeClass('fa-square-o').addClass('fa-check-square'); + $("#sortText").fadeOut(function () { + $(this).text($this.text().trim()); + }).fadeIn(); }); diff --git a/Ombi.UI/Models/Admin/CustomizationViewModel.cs b/Ombi.UI/Models/Admin/CustomizationViewModel.cs index 1c6082af3..568182a10 100644 --- a/Ombi.UI/Models/Admin/CustomizationViewModel.cs +++ b/Ombi.UI/Models/Admin/CustomizationViewModel.cs @@ -37,13 +37,19 @@ namespace Ombi.UI.Models.Admin public class CustomizationViewModel { public CustomizationSettings Settings { get; set; } - public List> LanguageDropdown { get; set; } = new List>(); - public List> FilterOptions { get; set; } = new List>(); + public List> LanguageDropdown { get; } = new List>(); + public List> FilterOptions { get; } = new List>(); public List> SortOptions { get; set; } = new List>(); } public enum FilterOptions { + [Display(Name = "all", Description = "All")] + All, + [Display(Name = ".approved-true", Description = "Approved")] + Approved, + [Display(Name = ".approved-false", Description = "Not Approved")] + NotApproved, [Display(Name = ".available-true", Description = "Available")] Available, [Display(Name = ".available-false", Description = "Not Available")] diff --git a/Ombi.UI/Models/Requests/RequestsIndexViewModel.cs b/Ombi.UI/Models/Requests/RequestsIndexViewModel.cs new file mode 100644 index 000000000..b95b96273 --- /dev/null +++ b/Ombi.UI/Models/Requests/RequestsIndexViewModel.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: RequestsIndexViewModel.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 Ombi.Core.SettingModels; + +namespace Ombi.UI.Models.Requests +{ + public class RequestsIndexViewModel + { + public PlexRequestSettings PlexRequestSettings { get; set; } + public CustomizationSettings CustomizationSettings { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.UI/Modules/RequestsModule.cs b/Ombi.UI/Modules/RequestsModule.cs index 5d9d8596f..f0c0934ac 100644 --- a/Ombi.UI/Modules/RequestsModule.cs +++ b/Ombi.UI/Modules/RequestsModule.cs @@ -44,6 +44,7 @@ using Ombi.Services.Notification; using Ombi.Store; using Ombi.UI.Models; using Ombi.UI.Models.Admin; +using Ombi.UI.Models.Requests; using Action = Ombi.Helpers.Analytics.Action; using ISecurityExtensions = Ombi.Core.ISecurityExtensions; @@ -117,7 +118,9 @@ namespace Ombi.UI.Modules private async Task LoadRequests() { var settings = await PrSettings.GetSettingsAsync(); - return View["Index", settings]; + var custom = await CustomizationSettings.GetSettingsAsync(); + + return View["Index", new RequestsIndexViewModel { CustomizationSettings = custom, PlexRequestSettings = settings }]; } private async Task GetMovies() @@ -227,7 +230,7 @@ namespace Ombi.UI.Modules } catch (Exception e) { - Log.Info(e); + Log.Info(e); } } @@ -316,7 +319,7 @@ namespace Ombi.UI.Modules return Response.AsJson(new JsonResponseModel { Result = true }); } - + Analytics.TrackEventAsync(Category.Requests, Action.Delete, "Delete Request", Username, CookieHelper.GetAnalyticClientId(Cookies)); var currentEntity = await Service.GetAsync(requestid); diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index 0a151d769..38a6bdf40 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -245,6 +245,7 @@ + diff --git a/Ombi.UI/Views/Requests/Index.cshtml b/Ombi.UI/Views/Requests/Index.cshtml index 9134aff07..0447e25fa 100644 --- a/Ombi.UI/Views/Requests/Index.cshtml +++ b/Ombi.UI/Views/Requests/Index.cshtml @@ -1,8 +1,12 @@ @using Nancy.Security @using Nancy.Security +@using Ombi.Helpers @using Ombi.Helpers.Permissions @using Ombi.UI.Helpers +@using Ombi.UI.Models.Admin @using Ombi.UI.Resources + +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @{ var baseUrl = Html.GetBaseUrl(); var formAction = string.Empty; @@ -11,29 +15,42 @@ { formAction = "/" + baseUrl.ToHtmlString(); } + + var sortText = EnumHelper.GetDisplayDescription((SortOptions) Model.CustomizationSettings.DefaultSort); + var filterText = EnumHelper.GetDisplayDescription((FilterOptions) Model.CustomizationSettings.DefaultFilter); + var defaultFilter = EnumHelper.GetDisplayValue((FilterOptions) Model.CustomizationSettings.DefaultFilter); + var defaultSort = EnumHelper.GetDisplayValue((SortOptions) Model.CustomizationSettings.DefaultSort); + }
- + + + + + + + +

@UI.Requests_Title

@UI.Requests_Paragraph

-
+
-
+
- @if (Model.SearchForMovies) + @if (Model.PlexRequestSettings.SearchForMovies) {
-
-
+
+
} - @if (Model.SearchForTvShows) + @if (Model.PlexRequestSettings.SearchForTvShows) {
-
-
+
+
} - @if (Model.SearchForMusic) + @if (Model.PlexRequestSettings.SearchForMusic) {
-
-
+
+
@@ -202,12 +199,12 @@ {{status}} {{#if denied}}
- Denied: + Denied: {{#if deniedReason}} {{/if}}
- + {{/if}} {{#if_eq releaseDate "01/01/0001 00:00:00"}}
@UI.Requests_ReleaseDate: {{releaseDate}}
@@ -234,7 +231,7 @@ {{/if_eq}}
- + {{#if_eq type "tv"}} {{#if episodes}} Episodes: @@ -284,7 +281,7 @@
-