mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Some work on the feature managment UI
- start of dependency aware feature disable/enable - bit of a perf improvement when working with the available features list (thanks, ToList, as usual) --HG-- branch : dev
This commit is contained in:
@@ -44,44 +44,12 @@ namespace Orchard.Modules.Controllers {
|
||||
});
|
||||
}
|
||||
|
||||
public ActionResult Features(FeaturesOptions options) {
|
||||
public ActionResult Features() {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var features = _moduleService.GetAvailableFeatures();
|
||||
return View(new FeaturesViewModel {Features = features, Options = options});
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Features")]
|
||||
[FormValueRequired("submit.BulkEdit")]
|
||||
public ActionResult FeaturesPOST(FeaturesOptions options, IList<string> selection) {
|
||||
if (selection != null && selection.Count > 0)
|
||||
{
|
||||
switch (options.BulkAction)
|
||||
{
|
||||
case FeaturesBulkAction.None:
|
||||
break;
|
||||
case FeaturesBulkAction.Enable:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to enable features")))
|
||||
return new HttpUnauthorizedResult();
|
||||
_moduleService.EnableFeatures(selection);
|
||||
//todo: (heskew) need better messages
|
||||
//todo: (heskew) hmmm...need a helper to comma-separate all but last, which would get the " and " treatment...all localized, of course
|
||||
Services.Notifier.Information(T("{0} were enabled", string.Join(", ", selection.ToArray())));
|
||||
break;
|
||||
case FeaturesBulkAction.Disable:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to disable features")))
|
||||
return new HttpUnauthorizedResult();
|
||||
_moduleService.DisableFeatures(selection);
|
||||
//todo: (heskew) need better messages
|
||||
Services.Notifier.Information(T("{0} were disabled", string.Join(", ", selection.ToArray())));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
return RedirectToAction("Features");
|
||||
return View(new FeaturesViewModel {Features = features});
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
@@ -107,7 +75,7 @@ namespace Orchard.Modules.Controllers {
|
||||
return new NotFoundResult();
|
||||
|
||||
_moduleService.DisableFeatures(new[] { featureName });
|
||||
Services.Notifier.Information(T("{0} was disabled", featureName));
|
||||
//Services.Notifier.Information(T("{0} was disabled", featureName));
|
||||
|
||||
return RedirectToAction("Features");
|
||||
}
|
||||
|
@@ -48,10 +48,11 @@ namespace Orchard.Modules.Services {
|
||||
}
|
||||
|
||||
public IEnumerable<IModuleFeature> GetAvailableFeatures() {
|
||||
var enabledFeatures = _shellDescriptorManager.GetShellDescriptor().EnabledFeatures;
|
||||
var enabledFeatures = _shellDescriptorManager.GetShellDescriptor().EnabledFeatures.ToList();
|
||||
return GetInstalledModules()
|
||||
.SelectMany(m => _extensionManager.LoadFeatures(m.Features))
|
||||
.Select(f => AssembleModuleFromDescriptor(f, enabledFeatures.FirstOrDefault(sf => string.Equals(sf.Name, f.Descriptor.Name, StringComparison.OrdinalIgnoreCase)) != null));
|
||||
.Select(f => AssembleModuleFromDescriptor(f, enabledFeatures.FirstOrDefault(sf => string.Equals(sf.Name, f.Descriptor.Name, StringComparison.OrdinalIgnoreCase)) != null))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<Feature> GetAvailableFeaturesByModule(string moduleName) {
|
||||
@@ -69,9 +70,20 @@ namespace Orchard.Modules.Services {
|
||||
|
||||
public void DisableFeatures(IEnumerable<string> featureNames) {
|
||||
var shellDescriptor = _shellDescriptorManager.GetShellDescriptor();
|
||||
|
||||
var enabledFeatures = shellDescriptor.EnabledFeatures.ToList();
|
||||
enabledFeatures.RemoveAll(f => featureNames.Contains(f.Name));
|
||||
var features = GetAvailableFeatures();
|
||||
|
||||
foreach (var featureName in featureNames) {
|
||||
var feature = featureName;
|
||||
var dependants = features.Where(f => f.IsEnabled && f.Descriptor.Dependencies != null && f.Descriptor.Dependencies.Contains(feature));
|
||||
|
||||
if (dependants.Count() == 0) {
|
||||
enabledFeatures.RemoveAll(f => f.Name == feature);
|
||||
}
|
||||
else {
|
||||
// list what else will be disabled with ok/cancel
|
||||
}
|
||||
}
|
||||
|
||||
_shellDescriptorManager.UpdateShellDescriptor(shellDescriptor.SerialNumber, enabledFeatures, shellDescriptor.Parameters);
|
||||
}
|
||||
|
@@ -4,16 +4,5 @@ using Orchard.Mvc.ViewModels;
|
||||
namespace Orchard.Modules.ViewModels {
|
||||
public class FeaturesViewModel : BaseViewModel {
|
||||
public IEnumerable<IModuleFeature> Features { get; set; }
|
||||
public FeaturesOptions Options { get; set; }
|
||||
}
|
||||
|
||||
public class FeaturesOptions {
|
||||
public FeaturesBulkAction BulkAction { get; set; }
|
||||
}
|
||||
|
||||
public enum FeaturesBulkAction {
|
||||
None,
|
||||
Enable,
|
||||
Disable
|
||||
}
|
||||
}
|
@@ -2,62 +2,53 @@
|
||||
<%@ Import Namespace="Orchard.Mvc.Html"%>
|
||||
<%@ Import Namespace="Orchard.Modules.ViewModels"%>
|
||||
<h1><%=Html.TitleForPage(T("Manage Features").ToString()) %></h1>
|
||||
<div class="manage" style="visibility:hidden"><%=Html.ActionLink(T("∞").ToString(), "Features", new { }, new { @class = "button primaryAction" })%></div>
|
||||
<% if (Model.Features.Count() > 0) {
|
||||
|
||||
using (Html.BeginFormAntiForgeryPost()) { %>
|
||||
<%=Html.ValidationSummary()%>
|
||||
<fieldset class="actions bulk">
|
||||
<label for="publishActions"><%=_Encoded("Actions: ")%></label>
|
||||
<select id="publishActions" name="<%=Html.NameOf(m => m.Options.BulkAction) %>">
|
||||
<%=Html.SelectOption(Model.Options.BulkAction, FeaturesBulkAction.None, _Encoded("Choose action...").ToString())%>
|
||||
<%=Html.SelectOption(Model.Options.BulkAction, FeaturesBulkAction.Enable, _Encoded("Enable").ToString())%>
|
||||
<%=Html.SelectOption(Model.Options.BulkAction, FeaturesBulkAction.Disable, _Encoded("Disable").ToString())%>
|
||||
</select>
|
||||
<input class="button" type="submit" name="submit.BulkEdit" value="<%=_Encoded("Apply") %>" />
|
||||
</fieldset>
|
||||
<fieldset class="pageList">
|
||||
<ul class="contentItems"><%
|
||||
foreach (var featureGroup in Model.Features.OrderBy(f => f.Descriptor.Category).GroupBy(f => f.Descriptor.Category)) { %>
|
||||
<li<%=featureGroup == Model.Features.Last() ? " class=\"last\"" : "" %>>
|
||||
<h2><%=Html.Encode(featureGroup.First().Descriptor.Category ?? T("Uncategorized")) %></h2>
|
||||
<ul><%
|
||||
foreach (var feature in featureGroup.OrderBy(f => f.Descriptor.Name)) {%>
|
||||
<li<%=feature == featureGroup.Last() ? " class=\"last\"" : "" %> id="<%=Html.Encode(feature.Descriptor.Name) %>">
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
<input type="checkbox" name="selection" value="<%=Html.Encode(feature.Descriptor.Name) %>" />
|
||||
<h3><%=Html.Encode(feature.Descriptor.Name) %></h3>
|
||||
<ul class="pageStatus">
|
||||
<li><%
|
||||
//enabled or not
|
||||
if (feature.IsEnabled) { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/enabled.gif") %>" alt="<%=_Encoded("Enabled") %>" title="<%=_Encoded("This feature is currently enabled") %>" /><%=_Encoded("Enabled") %><%
|
||||
}
|
||||
else { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/disabled.gif") %>" alt="<%=_Encoded("Disabled") %>" title="<%=_Encoded("This feature is currently disabled") %>" /><%=_Encoded("Disabled")%><%
|
||||
} %>
|
||||
</li><%
|
||||
//dependencies
|
||||
if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Count() > 0) { %>
|
||||
<li> | <%=T("Depends on: {0}", string.Join(", ", feature.Descriptor.Dependencies.Select(s => Html.Link(Html.Encode(s), string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), Html.Encode(s)))).OrderBy(s => s).ToArray())) %></li><%
|
||||
} %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="related"><%
|
||||
if (feature.IsEnabled) { %>
|
||||
<a href="<%=Html.AntiForgeryTokenGetUrl(Url.Action("Disable", new { featureName = feature.Descriptor.Name, area = "Orchard.Modules" })) %>"><%=_Encoded("Disable") %></a><%
|
||||
} else { %>
|
||||
<a href="<%=Html.AntiForgeryTokenGetUrl(Url.Action("Enable", new { featureName = feature.Descriptor.Name, area = "Orchard.Modules" })) %>"><%=_Encoded("Enable") %></a><%
|
||||
} %>
|
||||
</div>
|
||||
</div>
|
||||
</li><%
|
||||
} %>
|
||||
</ul>
|
||||
<% if (Model.Features.Count() > 0) { %>
|
||||
<ul class="contentItems"><%
|
||||
var featureGroups = Model.Features.OrderBy(f => f.Descriptor.Category).GroupBy(f => f.Descriptor.Category);
|
||||
foreach (var featureGroup in featureGroups) { %>
|
||||
<li<%=featureGroup == featureGroups.Last() ? " class=\"last\"" : "" %>>
|
||||
<h2><%=Html.Encode(featureGroup.First().Descriptor.Category ?? T("Uncategorized")) %></h2>
|
||||
<ul><%
|
||||
var features = featureGroup.OrderBy(f => f.Descriptor.Name);
|
||||
foreach (var feature in features) {%>
|
||||
<li<%=feature == features.Last() ? " class=\"last\"" : "" %> id="<%=Html.Encode(feature.Descriptor.Name) %>">
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
<h3><%=Html.Encode(feature.Descriptor.Name) %></h3>
|
||||
<ul class="pageStatus">
|
||||
<li><%
|
||||
//enabled or not
|
||||
if (feature.IsEnabled) { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/enabled.gif") %>" alt="<%=_Encoded("Enabled") %>" title="<%=_Encoded("This feature is currently enabled") %>" /><%=_Encoded("Enabled") %><%
|
||||
}
|
||||
else { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/disabled.gif") %>" alt="<%=_Encoded("Disabled") %>" title="<%=_Encoded("This feature is currently disabled") %>" /><%=_Encoded("Disabled")%><%
|
||||
} %>
|
||||
</li><%
|
||||
//dependencies
|
||||
if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Count() > 0) { %>
|
||||
<li> | <%=T("Depends on: {0}", string.Join(", ", feature.Descriptor.Dependencies.Select(s => Html.Link(Html.Encode(s), string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), Html.Encode(s)))).OrderBy(s => s).ToArray())) %></li><%
|
||||
} %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="related"><%
|
||||
if (feature.IsEnabled) {
|
||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Disable", new { area = "Orchard.Modules" }), Html.AttributeEncode(feature.Descriptor.Name)), FormMethod.Post, new {@class = "inline link"})) { %>
|
||||
<%=Html.Hidden("featureName", feature.Descriptor.Name) %>
|
||||
<button type="submit"><%=_Encoded("Disable") %></button><%
|
||||
}
|
||||
} else {
|
||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Enable", new { area = "Orchard.Modules" }), Html.AttributeEncode(feature.Descriptor.Name)), FormMethod.Post, new {@class = "inline link"})) { %>
|
||||
<%=Html.Hidden("featureName", feature.Descriptor.Name) %>
|
||||
<button type="submit"><%=_Encoded("Enable") %></button><%
|
||||
}
|
||||
} %>
|
||||
</div>
|
||||
</div>
|
||||
</li><%
|
||||
} %>
|
||||
</ul><%
|
||||
} %>
|
||||
</fieldset><%
|
||||
</ul>
|
||||
</li><%
|
||||
} %>
|
||||
</ul><%
|
||||
} %>
|
Reference in New Issue
Block a user