Quality now has sortable lists for configuring Profiles, saving not implemented yet.
This commit is contained in:
parent
be6bdbc483
commit
6d790f8939
|
@ -9,6 +9,7 @@ namespace NzbDrone.Core.Repository.Quality
|
||||||
{
|
{
|
||||||
[SubSonicPrimaryKey(true)]
|
[SubSonicPrimaryKey(true)]
|
||||||
public int ProfileId { get; set; }
|
public int ProfileId { get; set; }
|
||||||
|
|
||||||
[DisplayName("Name")]
|
[DisplayName("Name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool UserProfile { get; set; } //Allows us to tell the difference between default and user profiles
|
public bool UserProfile { get; set; } //Allows us to tell the difference between default and user profiles
|
||||||
|
@ -17,6 +18,11 @@ namespace NzbDrone.Core.Repository.Quality
|
||||||
[DisplayName("Allowed Qualities")]
|
[DisplayName("Allowed Qualities")]
|
||||||
public List<QualityTypes> Allowed { get; set; }
|
public List<QualityTypes> Allowed { get; set; }
|
||||||
|
|
||||||
|
[SubSonicIgnore]
|
||||||
|
[DisplayName("Allowed Qualities String")]
|
||||||
|
public string AllowedString { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("Cutoff")]
|
||||||
public QualityTypes Cutoff { get; set; }
|
public QualityTypes Cutoff { get; set; }
|
||||||
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
|
|
@ -98,8 +98,6 @@ namespace NzbDrone.Web.Controllers
|
||||||
{
|
{
|
||||||
ViewData["viewName"] = "Quality";
|
ViewData["viewName"] = "Quality";
|
||||||
|
|
||||||
var userProfiles = _qualityProvider.GetAllProfiles().Where(q => q.UserProfile).ToList();
|
|
||||||
var profiles = _qualityProvider.GetAllProfiles().ToList();
|
|
||||||
var qualityTypes = new List<QualityTypes>();
|
var qualityTypes = new List<QualityTypes>();
|
||||||
|
|
||||||
foreach (QualityTypes qual in Enum.GetValues(typeof(QualityTypes)))
|
foreach (QualityTypes qual in Enum.GetValues(typeof(QualityTypes)))
|
||||||
|
@ -107,6 +105,11 @@ namespace NzbDrone.Web.Controllers
|
||||||
qualityTypes.Add(qual);
|
qualityTypes.Add(qual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewData["Qualities"] = qualityTypes;
|
||||||
|
|
||||||
|
var userProfiles = _qualityProvider.GetAllProfiles().Where(q => q.UserProfile).ToList();
|
||||||
|
var profiles = _qualityProvider.GetAllProfiles().ToList();
|
||||||
|
|
||||||
var defaultQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].ProfileId, true));
|
var defaultQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].ProfileId, true));
|
||||||
|
|
||||||
var selectList = new SelectList(profiles, "ProfileId", "Name");
|
var selectList = new SelectList(profiles, "ProfileId", "Name");
|
||||||
|
@ -115,7 +118,6 @@ namespace NzbDrone.Web.Controllers
|
||||||
{
|
{
|
||||||
Profiles = profiles,
|
Profiles = profiles,
|
||||||
UserProfiles = userProfiles,
|
UserProfiles = userProfiles,
|
||||||
Qualities = qualityTypes,
|
|
||||||
DefaultProfileId = defaultQualityProfileId,
|
DefaultProfileId = defaultQualityProfileId,
|
||||||
SelectList = selectList
|
SelectList = selectList
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using System.Web;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Web.Helpers
|
||||||
|
{
|
||||||
|
public static class HtmlPrefixScopeExtensions
|
||||||
|
{
|
||||||
|
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
|
||||||
|
|
||||||
|
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
|
||||||
|
{
|
||||||
|
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
|
||||||
|
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
|
||||||
|
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, itemIndex));
|
||||||
|
|
||||||
|
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
|
||||||
|
{
|
||||||
|
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
|
||||||
|
{
|
||||||
|
// We need to use the same sequence of IDs following a server-side validation failure,
|
||||||
|
// otherwise the framework won't render the validation error messages next to each item.
|
||||||
|
string key = idsToReuseKey + collectionName;
|
||||||
|
var queue = (Queue<string>)httpContext.Items[key];
|
||||||
|
if (queue == null) {
|
||||||
|
httpContext.Items[key] = queue = new Queue<string>();
|
||||||
|
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
|
||||||
|
if (!string.IsNullOrEmpty(previouslyUsedIds))
|
||||||
|
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
|
||||||
|
queue.Enqueue(previouslyUsedId);
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HtmlFieldPrefixScope : IDisposable
|
||||||
|
{
|
||||||
|
private readonly TemplateInfo templateInfo;
|
||||||
|
private readonly string previousHtmlFieldPrefix;
|
||||||
|
|
||||||
|
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
|
||||||
|
{
|
||||||
|
this.templateInfo = templateInfo;
|
||||||
|
|
||||||
|
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
|
||||||
|
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ namespace NzbDrone.Web.Models
|
||||||
{
|
{
|
||||||
public List<QualityProfile> Profiles { get; set; }
|
public List<QualityProfile> Profiles { get; set; }
|
||||||
public List<QualityProfile> UserProfiles { get; set; }
|
public List<QualityProfile> UserProfiles { get; set; }
|
||||||
public List<QualityTypes> Qualities { get; set; }
|
//public List<QualityTypes> Qualities { get; set; }
|
||||||
|
|
||||||
[DisplayName("Default Quality Profile")]
|
[DisplayName("Default Quality Profile")]
|
||||||
public int DefaultProfileId { get; set; }
|
public int DefaultProfileId { get; set; }
|
||||||
|
|
|
@ -82,11 +82,13 @@
|
||||||
<Compile Include="Global.asax.cs">
|
<Compile Include="Global.asax.cs">
|
||||||
<DependentUpon>Global.asax</DependentUpon>
|
<DependentUpon>Global.asax</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Helpers\HtmlPrefixScopeExtensions.cs" />
|
||||||
<Compile Include="Helpers\IsCurrentActionHelper.cs" />
|
<Compile Include="Helpers\IsCurrentActionHelper.cs" />
|
||||||
<Compile Include="Models\AccountModels.cs" />
|
<Compile Include="Models\AccountModels.cs" />
|
||||||
<Compile Include="Models\MappingModel.cs" />
|
<Compile Include="Models\MappingModel.cs" />
|
||||||
<Compile Include="Models\EpisodeModel.cs" />
|
<Compile Include="Models\EpisodeModel.cs" />
|
||||||
<Compile Include="Models\QualityModel.cs" />
|
<Compile Include="Models\QualityModel.cs" />
|
||||||
|
<Compile Include="Models\QualityProfileModel.cs" />
|
||||||
<Compile Include="Models\SettingsModels.cs" />
|
<Compile Include="Models\SettingsModels.cs" />
|
||||||
<Compile Include="Ninject.Web.Mvc\ControllerMissingBindingResolver.cs" />
|
<Compile Include="Ninject.Web.Mvc\ControllerMissingBindingResolver.cs" />
|
||||||
<Compile Include="Ninject.Web.Mvc\FilterInjector.cs" />
|
<Compile Include="Ninject.Web.Mvc\FilterInjector.cs" />
|
||||||
|
@ -267,10 +269,9 @@
|
||||||
<Content Include="Views\Settings\General.ascx" />
|
<Content Include="Views\Settings\General.ascx" />
|
||||||
<Content Include="Views\Settings\Index.aspx" />
|
<Content Include="Views\Settings\Index.aspx" />
|
||||||
<Content Include="Views\Settings\Indexers.ascx" />
|
<Content Include="Views\Settings\Indexers.ascx" />
|
||||||
|
<Content Include="Views\Settings\ProfileAllowedQualities.ascx" />
|
||||||
<Content Include="Views\Settings\Quality.ascx" />
|
<Content Include="Views\Settings\Quality.ascx" />
|
||||||
<Content Include="Views\Settings\SubMenu.ascx" />
|
<Content Include="Views\Settings\SubMenu.ascx" />
|
||||||
<Content Include="Views\Settings\Test.ascx" />
|
|
||||||
<Content Include="Views\Settings\Test2.ascx" />
|
|
||||||
<Content Include="Views\Settings\UserProfileSection.ascx" />
|
<Content Include="Views\Settings\UserProfileSection.ascx" />
|
||||||
<Content Include="Views\Shared\Footer.ascx" />
|
<Content Include="Views\Shared\Footer.ascx" />
|
||||||
<Content Include="Web.config">
|
<Content Include="Web.config">
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
|
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
|
||||||
|
<%@ Import Namespace="NzbDrone.Core.Repository.Quality" %>
|
||||||
|
|
||||||
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
|
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
|
||||||
Settings
|
Settings
|
||||||
|
@ -10,6 +11,5 @@
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
|
|
||||||
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
|
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
|
||||||
|
|
||||||
<% Html.RenderPartial(ViewData["viewName"].ToString()); %>
|
<% Html.RenderPartial(ViewData["viewName"].ToString()); %>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NzbDrone.Web.Models.QualityModel>" %>
|
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NzbDrone.Web.Models.QualityModel>" %>
|
||||||
<%@ Import Namespace="NzbDrone.Core.Repository.Quality" %>
|
<%@ Import Namespace="NzbDrone.Core.Repository.Quality" %>
|
||||||
|
<%@ Import Namespace="NzbDrone.Web.Helpers" %>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
@ -62,26 +63,28 @@
|
||||||
<% using (Html.BeginForm("SaveQuality", "Settings", FormMethod.Post, new { id = "form", name = "form" }))
|
<% using (Html.BeginForm("SaveQuality", "Settings", FormMethod.Post, new { id = "form", name = "form" }))
|
||||||
{%>
|
{%>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Indexers</legend>
|
<legend>Quality</legend>
|
||||||
<%: Html.ValidationSummary(true, "Unable to save your settings. Please correct the errors and try again.") %>
|
<%: Html.ValidationSummary(true, "Unable to save your settings. Please correct the errors and try again.") %>
|
||||||
|
|
||||||
<div class="editor-label">
|
<div class="editor-label">
|
||||||
<%= Html.LabelFor(m => m.DefaultProfileId) %>
|
<%= Html.LabelFor(m => m.DefaultProfileId)%>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-field">
|
<div class="editor-field">
|
||||||
<%: Html.DropDownListFor(m => m.DefaultProfileId, Model.SelectList)%>
|
<%: Html.DropDownListFor(m => m.DefaultProfileId, Model.SelectList)%>
|
||||||
<%= Html.ValidationMessageFor(m => m.DefaultProfileId)%>
|
<%= Html.ValidationMessageFor(m => m.DefaultProfileId)%>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
<div id="profile-editor">
|
<div id="profile-editor">
|
||||||
<%= Html.ActionLink("Add a New Profile", "AddUserProfile", null, new { id = "addItem" }) %>
|
<%= Html.ActionLink("Add a New Profile", "AddUserProfile", null, new { id = "addItem" }) %>
|
||||||
<div id="user-profiles">
|
<div id="user-profiles">
|
||||||
<%for (int i = 0; i < Model.UserProfiles.Count(); i++){%>
|
<%foreach (var item in Model.UserProfiles) { %>
|
||||||
<% Html.RenderPartial("UserProfileSection", Model.UserProfiles[i]); %>
|
<% Html.RenderPartial("UserProfileSection", item); %>
|
||||||
<%--<%= Html.TextBoxFor(m => m.UserProfiles[i].ApiUrl, new { @style = "display:none" })%>--%>
|
<% } %>
|
||||||
<%}%>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<input type="submit" class="button" value="Save" />
|
<input type="submit" class="button" value="Save" />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -89,16 +92,6 @@
|
||||||
<%}%>
|
<%}%>
|
||||||
<div id="result"></div>
|
<div id="result"></div>
|
||||||
|
|
||||||
<%--<script type="text/javascript">
|
|
||||||
$('#add-profile').click(
|
|
||||||
function () {
|
|
||||||
<% Model.UserProfiles.Add(new QualityProfile{Name = "New Quality"}); %>
|
|
||||||
$('<%: Html.LabelFor(m => m.UserProfiles.Last().Name) %><%: Html.TextBoxFor(m => m.UserProfiles.Last().Name) %><br/>')
|
|
||||||
.prependTo($('#user-profiles'));
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>--%>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
$("#addItem").click(function () {
|
$("#addItem").click(function () {
|
||||||
|
@ -111,7 +104,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$("a.deleteRow").live("click", function () {
|
$("a.deleteRow").live("click", function () {
|
||||||
$(this).parents("div.editorRow:first").remove();
|
$(this).parents("div.userProfileSectionEditor:first").remove();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
|
@ -1,9 +1,87 @@
|
||||||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NzbDrone.Core.Repository.Quality.QualityProfile>" %>
|
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NzbDrone.Core.Repository.Quality.QualityProfile>" %>
|
||||||
|
<%@ Import Namespace="NzbDrone.Web.Helpers" %>
|
||||||
|
<%@ Import Namespace="NzbDrone.Core.Repository.Quality" %>
|
||||||
|
|
||||||
<div class="editor-label">
|
<% using (Html.BeginCollectionItem("UserProfiles"))
|
||||||
<%= Html.LabelFor(m => m.Name) %>
|
{ %>
|
||||||
</div>
|
|
||||||
<div class="editor-field">
|
<style type="text/css">
|
||||||
<%: Html.TextBoxFor(m => m.Name)%>
|
#sortable1, #sortable2 { list-style-type: none; margin: 0; padding: 0; float: left; margin-right: 10px; background: #eee; padding: 5px; width: 143px;}
|
||||||
<%= Html.ValidationMessageFor(m => m.Name)%>
|
#sortable1 li, #sortable2 li { margin: 5px; padding: 5px; font-size: 1.2em; width: 120px; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function () {
|
||||||
|
$("#sortable1, #sortable2").sortable({
|
||||||
|
connectWith: ".connectedSortable",
|
||||||
|
placeholder: "ui-state-highlight",
|
||||||
|
dropOnEmpty: true,
|
||||||
|
update: function (event, ui) {
|
||||||
|
|
||||||
|
var order = $('#sortable1').sortable("toArray");
|
||||||
|
$("#allowedString").val(order);
|
||||||
|
}
|
||||||
|
}).disableSelection();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="userProfileSectionEditor">
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
|
||||||
|
<%= Html.TextBoxFor(m => m.AllowedString, new { @id = "allowedString", @style = "display:none" })%>
|
||||||
|
<%--<%= Html.TextBoxFor(m => m.AllowedString, new { @id = "allowedString" })%>--%>
|
||||||
|
|
||||||
|
<label><%= Model.Name %></label>
|
||||||
|
<div class="removeDiv"><a href="#" class="deleteRow">Remove</a></div>
|
||||||
|
|
||||||
|
<div class="editor-label">
|
||||||
|
<%= Html.LabelFor(x => x.Name)%>
|
||||||
|
</div>
|
||||||
|
<div class="editor-field">
|
||||||
|
<%= Html.TextBoxFor(x => x.Name) %>
|
||||||
|
<%= Html.ValidationMessageFor(x => x.Name)%>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hiddenProfileDetails">
|
||||||
|
<%= Html.TextBoxFor(x => x.ProfileId, new { @style = "display:none" })%>
|
||||||
|
<%= Html.CheckBoxFor(x => x.UserProfile, new { @style = "display:none" })%>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div class="allowedQualities">
|
||||||
|
<ul id="sortable1" class="connectedSortable" title="Allowed">
|
||||||
|
<%for (int i = 0; i < Model.Allowed.Count(); i++){%>
|
||||||
|
<li class="ui-state-default" id="<%= Model.Allowed[i].ToString() %>">
|
||||||
|
<%= Html.DisplayTextFor(c => c.Allowed[i]) %>
|
||||||
|
</li>
|
||||||
|
<%}%>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="otherQualities">
|
||||||
|
<ul id="sortable2" class="connectedSortable">
|
||||||
|
<% var qualitiesList = (List<QualityTypes>) ViewData["Qualities"]; %>
|
||||||
|
|
||||||
|
<%for (int i = 0; i < qualitiesList.Count(); i++){%>
|
||||||
|
<%
|
||||||
|
//Skip Unknown and any item that is in the allowed list
|
||||||
|
if (qualitiesList[i].ToString() == "Unknown")
|
||||||
|
continue;
|
||||||
|
if (Model.Allowed.Contains(qualitiesList[i]))
|
||||||
|
continue;
|
||||||
|
%>
|
||||||
|
|
||||||
|
<li class="ui-state-default" id="<%= qualitiesList[i].ToString() %>">
|
||||||
|
<%= Html.Label(qualitiesList[i].ToString()) %>
|
||||||
|
<%--<%= Html.RenderPartial("ProfileAllowedQualities", Model.Allowed[i]) %>--%>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<% } %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
<% } %>
|
|
@ -58,7 +58,9 @@
|
||||||
.Add("jquery.jgrowl.js")
|
.Add("jquery.jgrowl.js")
|
||||||
.Add("Notification.js")
|
.Add("Notification.js")
|
||||||
.Add("jquery-tgc-countdown-1.0.js")
|
.Add("jquery-tgc-countdown-1.0.js")
|
||||||
.Add("jquery.simpledropdown.js"))
|
.Add("jquery.simpledropdown.js")
|
||||||
|
.Add("MicrosoftAjax.js")
|
||||||
|
.Add("MicrosoftMvcValidation.js"))
|
||||||
.Render();
|
.Render();
|
||||||
%>
|
%>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue